我有三个表 - tblpollquestions,tblpollanswers和tblpollresponses。
我想选择一个用户尚未回复的随机问题,并附上相应的答案。
下面的SQL完全返回我需要的内容,但我担心需要三个SELECT才能完成。肯定有更有效的方法吗?
SELECT
poll.id,
poll.question,
a.answer
FROM tblpollquestions poll
INNER JOIN tblpollanswers a ON a.question_id = poll.id
INNER JOIN (
SELECT id FROM tblpollquestions WHERE id NOT IN(
SELECT question_id FROM tblpollresponses WHERE user_id = 1
) ORDER BY RAND() LIMIT 1
) as t ON t.id = poll.id
答案 0 :(得分:0)
将NOT IN(SELECT...)
切换为LEFT JOIN
SELECT
poll.id,
poll.question,
a.answer
FROM
tblpollquestions poll
INNER JOIN
tblpollanswers a
ON
a.question_id = poll.id
INNER JOIN (
SELECT
q.id
FROM
tblpollquestions AS q
LEFT JOIN
tblpollresponses AS r
ON
q.id = r.question_id
AND r.user_id = 1
WHERE
r.question_id IS NULL
ORDER BY RAND() LIMIT 1
) as t ON t.id = poll.id
如果ORDER BY RAND()
表中有很多行, tblpollquestions
也会很慢。有关选择随机行的其他一些想法,请参阅Bill Karwin的演示文稿(幻灯片142及其后)。
http://www.slideshare.net/billkarwin/sql-antipatterns-strike-back
答案 1 :(得分:0)
对我来说似乎很好,虽然我会稍微改变一下:
SELECT
poll.id,
poll.question,
a.answer
FROM tblpollquestions poll
INNER JOIN tblpollanswers a ON a.question_id = poll.id
WHERE poll.id = (
SELECT id FROM tblpollquestions WHERE NOT EXISTS (
SELECT * FROM tblpollresponses WHERE user_id = 1 AND question_id = tblpollquestions.id )
ORDER BY RAND() LIMIT 1)
以这种方式编写应该更好地使用索引,而不是检查每个tblpollanswers
的连接条件。
确保确定 UNIQUE
tblpollresponses
上的(user_id, question_id)
索引(或主键)(按此顺序)。如果您需要其他查询,则可以按相反顺序添加其他UNIQUE
索引。
编辑:实际上将它放在可能不太好的地方http://jan.kneschke.de/projects/mysql/order-by-rand/您需要explain
查询并进行比较。
答案 2 :(得分:0)
像这样使用左连接:
SELECT ques.id, ques.question, ans.answer FROM tblpollquestions ques
INNER JOIN tblpollanswers ans ON(ans.question_id = ques.id)
left join tblpollresponses res on(res.question_id=ques.id and user_id = 1)
where res.question_id is null ORDER BY RAND() LIMIT 1;
我更改了表别名,以便更好地理解。