2011-01-26 64 views
2

我已經搜索了SO的答案,但似乎我的具體情況只是有點不同於其餘的。另一個複雜的MySQL訂購

基本上,我的數據由一些帶有「位置」(RoR中的acts_as_list)的「主」記錄組成,然後是任意數量的帶custom_position的「自定義」記錄以反映主位置。所需的結果是檢索一個包含master1,custom1,...,master2,custom2 ...,

的包含master + custom記錄的集合master記錄將具有NULL custom_position;自定義記錄將具有等於其主人位置的custom_position。

源數據,未排序:

 
name  sort_a sort_b 
====  ====== ====== 
Lorem  1  NULL 
ipsum  2  NULL 
dolor  3  NULL 
Lorem foo 4  1 
ipsum foo 5  2 
dolor foo 6  3 
Lorem bar 7  1 
ipsum bar 8  2 
dolor bar 9  3 
Lorem duck 10  1 
ipsum duck 11  2 
dolor duck 12  3 

所需的排序:

 
name  sort_a sort_b 
====  ====== ====== 
Lorem  1  NULL 
Lorem foo 4  1 
Lorem bar 7  1 
Lorem duck 10  1 
ipsum  2  NULL 
ipsum foo 5  2 
ipsum bar 8  2 
ipsum duck 11  2 
dolor  3  NULL 
dolor foo 6  3 
dolor bar 9  3 
dolor duck 12  3 

最接近我已經得到: 爲了通過聚結(sort_a,sort_b)ASC

 
name  sort_a sort_b 
====  ====== ====== 
Lorem foo 4  1 
Lorem bar 7  1 
Lorem duck 10  1 
Lorem  1  NULL 
ipsum foo 5  2 
ipsum bar 8  2 
ipsum duck 11  2 
ipsum  2  NULL 
dolor foo 6  3 
dolor bar 9  3 
dolor duck 12  3 
dolor  3  NULL 

任何想法如何在ORDER BY子句中實現所需的排序?

回答

5
SELECT * 
FROM mytable 
ORDER BY 
     COALESCE(sort_b, sort_a), sort_a 

查詢檢查:

SELECT * 
FROM (
     SELECT 'Lorem' AS name, 1 AS sort_a, NULL AS sort_b 
     UNION ALL 
     SELECT 'ipsum' AS name, 2 AS sort_a, NULL AS sort_b 
     UNION ALL 
     SELECT 'dolor' AS name, 3 AS sort_a, NULL AS sort_b 
     UNION ALL 
     SELECT 'Lorem foo' AS name, 4 AS sort_a, 1 AS sort_b 
     UNION ALL 
     SELECT 'ipsum foo' AS name, 5 AS sort_a, 2 AS sort_b 
     UNION ALL 
     SELECT 'dolor foo' AS name, 6 AS sort_a, 3 AS sort_b 
     UNION ALL 
     SELECT 'Lorem bar' AS name, 7 AS sort_a, 1 AS sort_b 
     UNION ALL 
     SELECT 'ipsum bar' AS name, 8 AS sort_a, 2 AS sort_b 
     UNION ALL 
     SELECT 'dolor bar' AS name, 9 AS sort_a, 3 AS sort_b 
     UNION ALL 
     SELECT 'Lorem duck' AS name, 10 AS sort_a, 1 AS sort_b 
     UNION ALL 
     SELECT 'ipsum duck' AS name, 11 AS sort_a, 2 AS sort_b 
     UNION ALL 
     SELECT 'dolor duck' AS name, 12 AS sort_a, 3 AS sort_b 
     ) q 
ORDER BY 
     COALESCE(sort_b, sort_a), sort_a 
+1

檢查OP中最後列表中的第8行,Ipsum,2,NULL將最終在Lorem Foo的前面,4,1。不好。 –

+0

@Ken Downs,也許Quassnoi修正了它,因爲測試查詢現在爲我返回正確的順序。 – jemminger

+0

謝謝!這看起來很完美。 – jemminger

0

這是一個有點棘手,但可以用一個UNION來完成。第一個子句用於NULL行,第二個子句用於其他子句:

select name 
    , sort_a 
    , sort_a as sort_b 
    from myTable 
where sort_b is null 
UNION ALL 
select name 
    , sort_a 
    , sort_b 
    from myTable 
where sort_b is NOT null 
order by 3,2 

請注意,在UNION查詢中,您使用列號而不是名稱進行排序。