Reputation: 21
I'm working on a problem where I have two tables the first one sort of like this:
id | value
1 d
2 e
3 s
4 g
and another like this
value
d
e
e
s
s
and I need to order them according to the number of times they occur in the second table so e would be first since it occurs 2 times and ahead of s by alphabetical order and then d. So the end result should be something like this
id | value
2 e
3 s
1 d
4 g
Currently I have this which does almost exactly what I want
SELECT table1.id, ordering.count
FROM table1,
(SELECT value, COUNT(*) AS count
FROM table2
GROUP BY value
ORDER BY count) AS ordering
WHERE table1.value = ordering.value
ORDER BY ordering.count DESC, table1.value;
The only problem is because g does not appear in table2, the result is the result I want but without the last row with g since it does not appear in the ordering table. Is there a way I can get it to order it as if it were 0 even though it doesn't appear in the list or is any way to get around this using what I currently have?
Any pointers are appreciated.
Upvotes: 1
Views: 40
Reputation: 133390
Why not a simply
SELECT table1.id, table1.value
FROM table2
INNER JOIN table2 on table1.value = table2.value
GROUP BY value
ORDER BY table2.count(*) desc, table1.value desc
Upvotes: 1
Reputation: 48169
You will need a LEFT-JOIN to your summary table...
SELECT
table1.id,
table1.value,
coalesce( ordering.count, 0 ) as FinalCount
FROM
table1
LEFT JOIN ( SELECT
value,
COUNT(*) AS count
FROM
table2
GROUP BY
value
ORDER BY count) AS ordering
ON table1.value = ordering.value
ORDER BY
COALESCE( ordering.count, 0 ) DESC,
table1.value
The left join says give me all records on the left-side table (your table 1 as it appears first) regardless of a match in the right-side (your subquery). However, IF it finds a record in the subquery, grab its count. The COALESCE() says if the first value is null, then use the next -- in this case, 0 if no match found.
Upvotes: 0