SQL简化

时间:2013-12-18 02:18:52

标签: mysql sql

我有这个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语句几乎都是相同的,很好地将它们排除在某种程度上。

由于

3 个答案:

答案 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