I need a list of item names ordered by count of items. Item names and corresponing id's are stored in tabletwo
while tableone
refers to items by id's:
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 code:
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
)
The nested SELECT
returns a list of item id's in descendant order: 3, 4, 1, 2
. This list is then used as an argument of an IN()
clause. The expected result of the whole query is: hurr, durr, foo, bar
(in this exact order). But the order is not preserved. I know it can be done like this: ORDER BY FIELD(id, 3, 4, 1, 2)
but I don't know how to do this trick when the ordered list is fetched dynamically like in my case. Do I need to SELECT
it again? Or temporary table maybe? Or is it better to build another query outside SQL?
Use JOIN
instead of 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
If you want to exclude rows from tabletwo
that do not have a match on tableone
, use INNER JOIN
instead of LEFT JOIN
.
Try using JOIN
instead:
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
You can create a derived table using the subquery of the IN
operator and perform a JOIN
to this table, so that you are able to use the COUNT
in the ORDER BY
clause of the main query.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.