我有这个SQL查询,它会计算属于所有现有Votes
的所有PollOptions
中的所有Polls
。这很好,但现在我想实现分页,它首先返回最新的Polls
。我试着这样做:
SELECT offset_polls.id AS pollId, offset_polls.title, poll_options.id AS pollOptionId, text, vote_count
FROM (
SELECT * FROM polls ORDER BY id DESC LIMIT 10 OFFSET 0
) as offset_polls
JOIN poll_options ON poll_options.poll_id = offset_polls.id
LEFT OUTER JOIN (
SELECT poll_option_id, COUNT(poll_option_id) as vote_count
FROM votes
GROUP BY poll_option_id
) as votesCount ON poll_options.id = votesCount.poll_option_id
ORDER BY offset_polls.id desc
问题是第一个子查询忽略了ORDER BY - 是的,我知道它的SQL标准。我这样做的方式,没有返回任何行。如果我在第一个子查询中不使用ORDER BY
,则整个查询的工作方式为“#en;”,但Polls
当然是从最旧的到最新的。我怎样才能在SQL中解决这个问题?之后我可以获取所有行并对它们进行分页,但我很确定这样效率很低 - (在Node.js中工作)。
修改
上述查询按预期工作。 ' bug'在我的数据库播种文件中。
答案 0 :(得分:1)
我检查了你的示例数据,我没有看到postgresql的行为有任何问题。当您运行查询
时会发生什么SELECT * FROM polls ORDER BY id DESC LIMIT 10 OFFSET 0
它会返回包含以下id
的所有民意调查:20
,19
,18
,...,11
。然后,您使用poll_options
加入这些行,并且您什么也得不到,因为在该范围内没有poll_id
的行:
# SELECT * FROM poll_options WHERE poll_id BETWEEN 11 AND 20;
id | text | poll_id
----+------+---------
(0 rows)
如果从ORDER BY
子查询中删除offset_polls
子句,则它将包含10个“随机”行,其中可能存在一些轮询选项,这就是查询返回某些行的原因。因此,ORDER BY
在这种情况下不会被忽略,并且行为完全如您所期望的那样。