我有一个objects
表和votes
表。我目前正在对它们进行分组并按最近的投票进行排序:
SELECT objects.id, objects.name, MAX(votes.created_at) AS mv
FROM "objects"
INNER JOIN "votes" ON "votes"."object_id" = "objects"."id"
GROUP BY objects.id, objects.name
ORDER BY mv DESC
但是,这只返回有投票的对象。我在SO上搜索并找到了关于如何包含不存在的结果的答案,但我希望包括那些存在的和不存在的结果。
有没有办法在上述所有没有投票的对象的结尾处?
答案 0 :(得分:1)
INNER JOIN
基本上返回两个表上都有记录的结果。然后,您应该使用LEFT JOIN
,因为它返回左侧的所有行,无论它是否在右表上都有匹配的记录。
SELECT objects.id, objects.name, MAX(votes.created_at) AS mv
FROM "objects"
LEFT JOIN "votes" ON "votes"."object_id" = "objects"."id"
GROUP BY objects.id, objects.name
ORDER BY mv DESC
<强> Visual Representation of JOINs 强>
希望这会有所帮助。
答案 1 :(得分:1)
如果找不到匹配的行,则会LEFT JOIN
填充NULL
,NULL
值为you found out yourself:
超级令人沮丧,因为它完美无缺,除了所有的 没有投票的条目就在开头!
现在,DESC
通常排序最后。但与NULL
相反,它首先来自 。在Postgres中,您可以使用NULLS LAST
将
SELECT o.id, o.name, max(v.created_at) AS lastest_vote
FROM objects o
LEFT JOIN votes v ON v.object_id = o.id
GROUP BY o.id, o.name
ORDER BY lastest_vote DESC NULLS LAST, o.name; -- name only as tiebreaker
显式排序到最后(从8.3版开始):
objects.id
如果GROUP BY
是主键,则可以简化GROUP BY o.id -- primary key covers all columns of this table
(在Postgres 9.1或更高版本中):
{{1}}
答案 2 :(得分:0)
使用"LEFT OUTER JOIN"
代替在您的对帐单中使用"INNER JOIN"
。
干杯