Sql 如何将多个子查询的结果相加?

Sql 如何将多个子查询的结果相加?,sql,mysql,Sql,Mysql,我正在运行一个MySQL查询,根据他们贡献的书评和食谱评论的数量对我网站的用户进行排名。在多连接查询的初始问题之后,我切换到一系列子查询,这要快得多。然而,尽管我可以提取每个成员的评论数量,但我不知道如何将它们加在一起,以便按总数排序 以下是当前的查询: SELECT users.*, (SELECT count(*) FROM bookshelf WHERE bookshelf.user_id = users.ID) as titles, (SELECT count(*) FROM

我正在运行一个MySQL查询,根据他们贡献的书评和食谱评论的数量对我网站的用户进行排名。在多连接查询的初始问题之后,我切换到一系列子查询,这要快得多。然而,尽管我可以提取每个成员的评论数量,但我不知道如何将它们加在一起,以便按总数排序

以下是当前的查询:

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   

我需要将书评和RecipereView加在一起以获得“书评总数”。MySQL不允许您使用简单的语法对别名进行计算,但我认为还有其他方法可以做到这一点???

您尝试了以下方法

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   
两种选择:

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

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

也许这会管用(还没试过)


将其包装到子查询中:

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

如果您希望安全快速,请按以下方式操作:

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
如果您希望坚持使用
选择
列表中的子查询,并希望它是安全的,请查看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   

谢谢-这差不多了,但我仍然需要从书评和RecipereView以及计算出的总数生成总数。第二个几乎可以工作,但你必须在第一个子查询中添加一个别名-然后它与@Quassnoi的解决方案完全相同,尽管这是在一分钟之前。谢谢有趣的是:选项1比Quassnoi的解决方案快一点点(0.02秒对0.024秒),而选项2是0.88秒,所以相对来说要慢一点。我发现Quassnoi在可读性(以及我对所发生事情的理解)方面要简单得多。在你的第一个例子中使用连接方法有什么好处吗?曼德尔:是的,当你处理的集合越来越大时,这些好处很快就会显现出来。联接具有更好的可伸缩性。然而,在这些时刻,我认为我们不能说任何结论。我不会理会这么小的差别。但当你得到更多的数据来处理时,你仍然会看到很大的差异。子查询解决方案为外部查询的每一行执行每个子查询。嵌套循环联接通常效率更高。@mandel,我很好奇你在
联接方面的问题通常,我用
联接解决这类问题-请参阅我的答案以供参考。根据我的经验,MySQL通常比您拥有的多个相关子查询快得多。我很想知道在您的情况下,子查询解决方案是否比连接更快。如果你能让我知道的话,我会非常感激。我和JOIN的问题是因为缺乏经验而不是哲学。我之前的加入导致了一个非常慢的查询——9秒;结果是它创造了一个笛卡尔的产品。我在网上问过,所以这里:。当我开始做子查询时,速度显著提高,我可以理解我在做什么!请参阅我对您文章的回答,以进行速度比较-您的加入查询稍微快一点,但在当前数据库大小下仅为4/100秒。
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 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