计算具有相同列的多个表的结果

时间:2011-04-13 06:09:20

标签: mysql count

我有一个系统,用户基本上可以输入3个不同的信息:提示,评论和投票。这些信息保存到3个不同的表中。每个表的链接列是用户ID。我想进行查询以确定用户是否具有任何三种类型的信息。我试图在一个查询中完成它,但它完全错了。以下是我现在正在使用的内容:

SELECT DISTINCT
  *
  FROM tips T
  LEFT JOIN comments C ON T.user_id = C.user_id
  LEFT JOIN votes V ON T.user_id = V.user_id
  WHERE T.user_id = 1

这似乎只是获得提示,即使投票或评论不是由指定的user_id进行,也可以复制多少票或评论。

我只需要一个数字作为回报,而不是每种类型的个别数量。我基本上想要在该user_id下保存的提示,评论和投票数量的总和,但我不想做三个查询。

有人有什么想法吗?

编辑:实际上,我在技术上甚至不需要实际计数,我只需要知道这三个表中是否有任何行与该user_id。

编辑2:我几乎拥有它:

SELECT
  COUNT(DISTINCT T.tip_id),
  COUNT(DISTINCT C.tip_id),
  COUNT(DISTINCT V.tip_id)
  FROM tips T
    LEFT JOIN comments C ON T.user_id = C.user_id
    LEFT JOIN votes V ON T.user_id = V.user_id
  WHERE T.user_id = 1

我正在使用user_id 1(我)进行测试。我做了11个提示,投了4次,没有发表评论。我的返回是一行有3列:11,0,4。这是正确的计数。但是,我测试了没有提出任何提示或评论的用户,但投票了3次,所有计数都返回0,它应该返回:0,0,3。

我遇到的问题似乎是,如果我用于WHERE子句的表没有来自该user_id的任何行,那么我全面得到0,即使其他表是DO拥有该user_id的行。我可以使用这个查询:

SELECT
  (SELECT COUNT(*) FROM tips WHERE user_id = 2) +
  (SELECT COUNT(*) FROM comments WHERE user_id = 2) +
  (SELECT COUNT(*) FROM votes WHERE user_id = 2) AS total

但我真的想避免运行多个查询,即使它们是这样的子查询。

更新

感谢王牌,我想出了这个:

SELECT
  (COUNT(DISTINCT T.tip_id) + COUNT(DISTINCT C.tip_id) + COUNT(DISTINCT V.tip_id)) AS total
  FROM users U
    LEFT JOIN tips T ON U.user_id = T.user_id
    LEFT JOIN votes V ON U.user_id = V.user_id
    LEFT JOIN comments C ON U.user_id = C.user_id
  WHERE U.user_id = 4

users表包含用户的实际信息,显然包括用户ID。我使用用户表作为父表,因为我可以100%确定用户将出现在该表中,即使它们不在其他表中。我通过此查询获得了正确的计数!

1 个答案:

答案 0 :(得分:1)

据我了解你的问题。您想要计算每个用户的总评论+提示+投票数。虽然我不是很清楚,但请看下面的查询。我添加了详细信息列,这是一个交叉标签查询,就像有人教我一样。

EDITED QUERY:

  SELECT
         COALESCE(COALESCE(t2.tips,0) + COALESCE(c2.comments,0) + COALESCE(v2.votes,0)) AS `Totals`
    FROM parent p
    LEFT JOIN (SELECT t.user_id, COUNT(t.tip_id) AS tips FROM tips t GROUP BY t.user_id) t2
      ON p.user_id = t2.user_id
    LEFT JOIN (SELECT c.user_id, COUNT(c.tip_id) AS comments FROM comments c GROUP BY c.user_id) c2
      ON p.user_id = c2.user_id               
    LEFT JOIN (SELECT v.user_id, COUNT(v.tip_id) AS votes FROM votes v GROUP BY v.user_id) v2
      ON p.user_id = v2.user_id
   WHERE p.user_id = 1;

注意:这使用父表来获取不在其他表中的表的结果。

我在JOIN中使用子查询的原因是创建一个虚拟表,它将获得每个表的tip_id总和。另外我使用你的同一查询DISTINCT有问题,所以我最终得到了这个查询。

我知道您不喜欢使用子查询,但我没有子查询就失败了。现在,这就是我所能做的。