我需要一个按项目数排序的项目名称列表。商品名称和相应的ID存储在tabletwo
中,而tableone
是指ID的商品:
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之外构建另一个查询是否更好?
答案 0 :(得分: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
。
答案 1 :(得分:3)
请尝试使用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
,以便您可以使用{{1}中的COUNT
主查询的子句。