如何将几个子查询的结果加在一起?

时间:2010-01-11 14:32:44

标签: sql mysql

我正在运行MySQL查询,根据他们贡献的书评和食谱评论的数量对我网站的用户进行排名。在多个JOIN查询的初始问题之后,我已经切换到一系列子查询,这要快得多。但是,虽然我可以从每个成员中提取评论数量,但我无法弄清楚如何将它们添加到一起,因此我可以按总数进行排序。

这是当前的查询:

SELECT users.*,
   (SELECT count(*) FROM bookshelf WHERE bookshelf.user_id = users.ID) as titles,
   (SELECT count(*) FROM book_reviews WHERE book_reviews.user_id = users.ID) as bookreviews,
   (SELECT count(*) FROM recipe_reviews WHERE recipe_reviews.user_id = users.ID) as recipereviews
FROM users   

我需要将bookreviews和recipereviews加在一起以获得'reviewtotals'。 MySQL不会允许你使用简单的语法来计算别名,但我认为还有另一种方法可以做到这一点?

4 个答案:

答案 0 :(得分:11)

将其包装到子查询中:

SELECT  *,
        bookreviews + recipereviews AS totalreviews
FROM    (
        SELECT  users.*,
                (SELECT count(*) FROM bookshelf WHERE bookshelf.user_id = users.ID) as titles,
                (SELECT count(*) FROM book_reviews WHERE book_reviews.user_id = users.ID) as bookreviews,
                (SELECT count(*) FROM recipe_reviews WHERE recipe_reviews.user_id = users.ID) as recipereviews
        FROM    users   
        ) q

答案 1 :(得分:1)

两个选项:

选项1:丑陋是地狱,可能很慢(取决于查询缓存):

SELECT users.*,
   (SELECT count(*) FROM bookshelf WHERE bookshelf.user_id = users.ID) as titles,
   (SELECT count(*) FROM book_reviews WHERE book_reviews.user_id = users.ID) as bookreviews,
   (SELECT count(*) FROM recipe_reviews WHERE recipe_reviews.user_id = users.ID) as recipereviews
   (SELECT count(*) FROM book_reviews WHERE book_reviews.user_id = users.ID) + (SELECT count(*) FROM recipe_reviews WHERE recipe_reviews.user_id = users.ID) as reviewtotals
FROM users   

选项2:将结果保存到临时表,然后查询此表

也许这会奏效(没试过)

SELECT *, bookreviews+recipereviews as reviewtotals FROM
(SELECT users.*,
   (SELECT count(*) FROM bookshelf WHERE bookshelf.user_id = users.ID) as titles,
   (SELECT count(*) FROM book_reviews WHERE book_reviews.user_id = users.ID) as bookreviews,
   (SELECT count(*) FROM recipe_reviews WHERE recipe_reviews.user_id = users.ID) as recipereviews
FROM users) u  

答案 2 :(得分:1)

如果您想要安全和快速,请这样做:

SELECT users.*
,      titles.num                            titles
,      book_reviews.num                      book_reviews
,      recipe_reviews.num                    recipe_reviews
,      book_reviews.num + recipe_reviews.num total_reviews
FROM      users   
LEFT JOIN (
          SELECT   user_ID, count(*) AS num
          FROM     bookshelf
          GROUP BY user_ID
          ) as titles
ON        users.ID = titles.user_ID
LEFT JOIN (
          SELECT   user_ID, count(*) AS num
          FROM     book_reviews
          GROUP BY user_ID
          ) as book_reviews
ON        users.ID = reviews.user_ID
LEFT JOIN (
          SELECT   user_ID, count(*) AS num
          FROM     recipe_reviews
          GROUP BY user_ID
          ) as recipe_reviews
ON        users.ID = recipes.user_ID

如果你想坚持SELECT列表中的子查询,并希望它是安全的,请看看Quassnoi的解决方案。

如果你想生活得有点危险并且仍然想要快速的结果,你可以使用用户定义的变量。我预测在这种特殊情况下它会安全:

SELECT users.*,
       (SELECT count(*) FROM bookshelf WHERE bookshelf.user_id = users.ID) as titles,
       @bookreviews:=(
           SELECT count(*) 
           FROM book_reviews 
           WHERE book_reviews.user_id = users.ID
       ) as bookreviews,
       @recipereviews:=(
           SELECT count(*) 
           FROM recipe_reviews 
           WHERE recipe_reviews.user_id = users.ID
       ) as recipereviews,
       @bookreviews + @recipereviews as total_reviews
FROM users   

答案 3 :(得分:0)

您尝试过以下操作?

SELECT users.*,
   (SELECT count(*) FROM bookshelf WHERE bookshelf.user_id = users.ID) as titles,
   ((SELECT count(*) FROM book_reviews WHERE book_reviews.user_id = users.ID) +
   (SELECT count(*) FROM recipe_reviews WHERE recipe_reviews.user_id = users.ID)) as reviewtotal
FROM users