2013-12-21 51 views
2

我有两个表。SQL排序与多个标准

TAB1:

+------------+ 
| id | title | 
+------------+ 
| 1 | B  | 
| 2 | C  | 
| 3 | A  | 
| 4 | A  | 
| 5 | A  | 
| 6 | A  | 
| ...  | 
+------------+ 

TAB2:

+-------------------------------------------+ 
| id | item_id | item_key |  item_value | 
+-------------------------------------------+ 
| 1 | 1  | value | $4    | 
| 2 | 1  | url  | http://h.com/ | 
| 3 | 2  | value | $5    | 
| 4 | 3  | url  | http://i.com/ | 
| 5 | 3  | value | $1    | 
| 6 | 3  | url  | http://y.com/ | 
| 7 | 4  | value | $2    | 
| 8 | 4  | url  | http://z.com/ | 
| 9 | 5  | value | $1    | 
| 10 | 5  | url  | http://123.com/ | 
| ...          | 
+-------------------------------------------+ 
  • ITEM_ID是从TAB1的外键。

我该如何做到这一点,所以我根据两个表中的条件按顺序从Tab1中获取ID表。标准如下:

  • 按标题订购ASC。如果标题相同,则按价值排序DESC
  • 。如果标题和值都相同,
  • 优先考虑'url'键包含'123.com'的项目。

与所订购的结果生成的表是:

+------------+ 
| id | title | 
+------------+ 
| 4 | A  | 
| 5 | A  | 
| 3 | A  | 
| 6 | A  | 
| 1 | B  | 
| 2 | C  | 
| ...  | 
+------------+ 

结果应当包括那些没有一个项目,这两者或没有从TAB2组字段。

回答

3

据我理解,一个简单的加入将做到这一点。您必须加入Tab2两次,因为您要按来自两行的值排序。

SELECT Tab1.id, Tab1.title 
FROM Tab1 
JOIN Tab2 t2_val ON t2_val.item_id = Tab1.id AND t2_val.item_key='value' 
JOIN Tab2 t2_url ON t2_url.item_id = Tab1.id AND t2_url.item_key='url' 
ORDER BY title, 
     t2_val.item_value DESC, 
     t2_url.item_value LIKE '%123.com%' DESC 

An SQLfiddle to test with

+0

任何想法如何使它在结果中包含tab1中没有'item_key'='value'或没有'item_key'='url'设置在tab2中的项目? – c10b10

+0

@ c10b10是的,普通[用'LEFT JOIN'替换'JOIN'](http://sqlfiddle.com/#!2/8c223/1)应该这样做,但是你想要的排序顺序并不能说明按照什么顺序如果缺少一行,请将它们放入。 –

+0

这很棒,因为那些东西只剩下最后一个。谢谢! – c10b10

2

有点复杂,因为当你做join你会得到多行。这里是做加盟前聚集tab2的方法:

select t1.* 
from Tab1 t1 left outer join 
    (select id, 
      max(case when item_key = 'value' then item_value end) as value, 
      max(case when item_key = 'url' then item_value end) as url 
     from Tab2 t2 
     group by id 
    ) t2 
    on t1.id = t2.id 
order by t1.title, t2.value desc, 
     (t2.url like '%123.com%') desc; 
+0

你没有时间回答:) +1 –

+0

你相信这比Joachim Isaksson的回答快吗? – c10b10

+0

@ c10b10。 。 。这取决于许多因素。但是,一般来说,MySQL比聚合更好地执行连接。 –