2013-12-18 36 views
3

我有这样的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` 

有没有一种方法,我可以在干燥方式做到这一点?两种选择语句几乎相同,将它们排除在外是很好的选择。

感谢

回答

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 
+0

谢谢,正是我在找的东西。我使用后者,因为帖子不能由同一用户进行多次投票。 – 0xSina

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
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`