我有这个SQL语句:
SELECT
(CASE
WHEN EXISTS
(SELECT *
FROM votes
WHERE votes.user_id = 0
AND votes.post_id = posts.id
AND votes.vote = 0) THEN 0
WHEN EXISTS
(SELECT *
FROM votes
WHERE votes.user_id = 0
AND votes.post_id = posts.id
AND votes.vote = 1) THEN 1
ELSE 2
END) AS vote_by_me ,
posts.*
FROM `posts`
有没有办法可以干涸的方式做到这一点?两个select语句几乎都是相同的,很好地将它们排除在某种程度上。
由于
答案 0 :(得分:1)
这似乎可以简化查询:
SELECT (CASE WHEN v.votes0 > 0 THEN 0
WHEN v.votes1 > 0 THEN 1
ELSE 2
END) AS vote_by_me,
p.*
FROM posts p left outer join
(select v.post_id, sum(v.vote = 1) as vote1, sum(v.vote = 0) as vote0
from votes v
where v.user_id = 0
group by v.post_id
) v
on p.post_id = v.post_id;
坏消息是,如果您在votes(user_id, post_id, votes)
上有索引,那么您的原始表单可能会有更好的效果。
编辑:
以下表述可能表现良好,并且可以简化查询:
SELECT (CASE (SELECT min(vote)
FROM votes
WHERE votes.user_id = 0 AND
votes.post_id = posts.id
)
WHEN 0 then 0
WHEN 1 then 1
ELSE 2
END) AS vote_by_me,
posts.*
FROM `posts`;
答案 1 :(得分:1)
SELECT
(CASE
WHEN EXISTS
(SELECT *
FROM votes
WHERE votes.user_id = 0
AND votes.post_id = posts.id
AND votes.vote IN (0,1) )THEN votes.vote
ELSE 2
END) AS vote_by_me ,
posts.*
FROM `posts`
答案 2 :(得分:1)
是的,您可以直接选择votes.vote
,如下所示:
SELECT
COALESCE(
(
SELECT MIN(votes.vote)
FROM votes
WHERE votes.user_id = 0 AND votes.post_id = posts.id
AND votes.vote in (0, 1)
GROUP BY votes.user_id, votes.post_id
)
, 2
) AS vote_by_me
, posts.*
FROM `posts
如果某个帖子不能由同一个用户进行多次投票,则可以删除GROUP BY
,如下所示:
SELECT
COALESCE(
(
SELECT votes.vote
FROM votes
WHERE votes.user_id = 0 AND votes.post_id = posts.id AND votes.vote in (0, 1)
)
, 2
) AS vote_by_me
, posts.*
FROM `posts