これを試して:
SELECT
name,
CASE WHEN parent_id = 0 THEN id ELSE parent_id END AS Sort
FROM
cars
ORDER BY
Sort,
id
http://sqlfiddle.com/#!2/9b05f/3
編集:
この回答が賛成票を獲得し続けていることを考えると、私は質問を再検討し、欠陥を見つけました。何らかの理由で、親の ID が子の ID よりも大きい場合、順序が乱れます。上記のクエリは、親 ID がすべての子よりも小さい数である場合にのみ機能します。
問題を説明するために、テーブルが次のようになっていると想像してください。
id parent_id name
8 0 BMW
2 0 Mercedez
3 0 Porsche
4 8 3 Series
5 2 E60
6 8 5 Series
7 3 Cayenne
1ではなく8BMW
があることid
に注意してください。結果は次のようになります。
Mercedez
E60
Porsche
Cayenne
3 Series
5 Series
BMW
上で、 BMW が子の後にリストの一番下に表示されていることに注意してください。これは、2 番目の並べ替え順序が によるものid
であり、親 ID がどの子よりも大きい場合、親が子の上に表示されない可能性があるためです。
このクエリはその問題を解決します。
SELECT
name
FROM
cars
ORDER BY
CASE WHEN parent_id = 0 THEN id ELSE parent_id END, -- another way of writing it: IFNULL(NULLIF(parent_id, 0), id)
parent_id,
id
http://sqlfiddle.com/#!2/6d6d73/3
ここで何が起こっているかを説明するために、まず親行のid
フィールドと子行のフィールドで並べ替えparent_id
ます。その順序で並べると、すべての子が親とグループ化され、全体のリストは親のid
フィールドで並べられます。
ただし、これはファミリー内の並べ替えを設定しないため、親はファミリー内のどこにでも表示される可能性があります (親が一番上に表示されるか、真ん中に表示されるか、最後に表示される可能性があります)。
そこで、他の 2 つの並べ替えフィールドの出番です。2 番目のフィールドは で並べ替えられparent_id
、親行のparent_id
フィールドは常に0
です。ID フィールドが常に正であると安全に仮定すると、これは、親レコードが常にファミリー内で一番上に表示されることを意味します。残りの子はすべて に対して同じ値を持つparent_id
ため、3 番目の並べ替えフィールドは、ファミリ内の子をフィールド別に並べ替えますid
。name
子をどのように並べ替えるかによって、これを に変更することもできます。