Search code examples
mysqlcoalesce

How to specify Primary sort order using MySQL COALESCE


I have a legacy table that uses Parent/Child structure with it's ID, and I need to sort it by the Names of the Parent, then the Child (Parents have null parent_id).

I've been able to get it to sort by the Child name with the SQL shown below, but am unable to get it to do the same for the primary (Cables should be before Cameras).

SELECT a.id, a.parent_id,a.name
FROM `equipment` AS a
ORDER BY COALESCE(a.parent_id, a.id), a.parent_id IS NOT NULL, a.name

I've tinkered with the various ORDER possibilities, but cannot get the sort that I need. Any guidance is appreciated.

Table Rows

id  | parent_id | name
--------------------------------
1   | null      | Cameras
2   | 1         | HandyCam 2000 5-50
3   | 1         | Netgear 360
4   | null      | Tripods
5   | 4         | Deluxe Tripod
6   | null      | Lighting
7   | 6         | Light Diffuser
10  | 6         | Really bright bulbs
11  | 1         | 16MM Handheld
12  | 6         | Big Lightbulb assembly
13  | 4         | HandyCam Stand
16  | 4         | My New Tripod
181 | null      | Cables

Sorted Results (with only Children being sorted)

id  | parent_id | name
--------------------------------
1   | null      | Cameras
11  | 1         |    16MM Handheld
2   | 1         |    HandyCam 2000 5-50
3   | 1         |    Netgear 360
4   | null      | Tripods
5   | 4         |    Deluxe Tripod
13  | 4         |    HandyCam Stand
16  | 4         |    My New Tripod
6   | null      | Lighting
10  | 6         |    Really bright bulbs
12  | 6         |    Big Lightbulb assembly
7   | 6         |   Light Diffuser
181 | null      | Cables

Solution

  • You need to join the table with itself, so you can get the name of the parent of each child, and use that in the sort instead of COALESCE(a.parent_id, a.id)

    SELECT a.id, a.parent_id,IF(a.parent_id IS NULL, a.name, CONCAT('   ', a.name)) AS name
    FROM `studio_tvs_equipment` AS a
    JOIN studio_tvs_equipment AS b ON IF(a.parent_id IS NULL, a.id = b.id, b.id = a.parent_id)
    ORDER BY IF(a.parent_id IS NULL, a.name, b.name), a.parent_id IS NOT NULL, a.name
    

    DEMO