2016-06-01 90 views
1

我需要按项目数排序的项目名称列表。项目名称和corresponing的ID存储在tabletwotableone是指物品通过ID的:保留SQL中的WHERE IN()子句的顺序SELECT

 tableone    tabletwo 
+--------+-----------+ +----+------+ 
| itemid | condition | | id | name | 
+--------+-----------+ +----+------+ 
| 2  | satisfied | | 1 | foo | 
+--------+-----------+ +----+------+ 
| 1  | satisfied | | 2 | bar | 
+--------+-----------+ +----+------+ 
| 3  | satisfied | | 3 | hurr | 
+--------+-----------+ +----+------+ 
| 3  | satisfied | | 4 | durr | 
+--------+-----------+ +----+------+ 
| 3  | satisfied | 
+--------+-----------+ 
| 4  | satisfied | 
+--------+-----------+ 
| 4  | satisfied | 
+--------+-----------+ 
| 3  | nope  | 
+--------+-----------+ 
| 1  | satisfied | 
+--------+-----------+ 

SQL代码:

SELECT `itemname` FROM `tabletwo` WHERE `id` IN (
    SELECT `itemid` FROM (
     SELECT count(`itemid`), `itemid` 
     FROM `tableone` 
     WHERE `some_codition`="satisfied" 
     GROUP BY `itemid` 
     ORDER BY count(`itemid`) DESC 
    ) alias 
) 

嵌套SELECT返回项目ID在后代顺序表:3, 4, 1, 2。此列表然后用作IN()子句的参数。 整个查询的预期结果是:hurr, durr, foo, bar(按此确切顺序)。但订单不会保留。我知道它可以这样做:ORDER BY FIELD(id, 3, 4, 1, 2)但我不知道如何做到这一点,当有序的列表被动态获取像我的情况。我需要SELECT吗?或临时表也许?或者更好地在SQL之外构建另一个查询?

+1

尝试使用'JOIN'来代替。 –

+0

指定预期结果。 – jarlh

回答

2

尝试使用JOIN代替:

SELECT t2.`itemname` 
FROM `tabletwo` AS t2 
JOIN ( 
    SELECT count(`itemid`) AS cnt, `itemid` 
    FROM `tableone` 
    WHERE `some_codition`="satisfied" 
    GROUP BY `itemid` 
) AS t1 ON t1.`itemid` = t2.`id` 
ORDER BY t1.cnt DESC 

可以使用IN运营商的子查询创建派生表并执行JOIN这个表,让你能在主查询的ORDER BY子句中使用COUNT

3

使用JOIN代替IN

SELECT 
    t2.name 
FROM tabletwo t2 
LEFT JOIN tableone t1 
    ON t1.itemid = t2.id 
    AND t1.`condition` = 'satisfied' 
GROUP BY 
    t2.id, t2.name 
ORDER BY COUNT(*) DESC 

如果你想排除tabletwo行没有对tableone匹配,使用INNER JOIN代替LEFT JOIN

ONLINE DEMO