2011-04-13 75 views
1

我有一个系统,用户可以在其中放入3种不同的信息:小费,评论和投票。这些信息被保存到3个不同的表格中。每个表的链接列是用户标识。我想要做一个查询来确定用户是否有任何三种类型的任何信息。我试图在单个查询中完成,但它完全错误。以下是我与现在的工作:从同一列的多个表中计算结果

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的任何行,那么即使其他表具有该user_id的行,我也会在整个板上得到0。我可以使用这个查询:

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 

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

UPDATE

感谢王牌,我想通了这一点:

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 

用户表包含回合的用户包括,显然,用户ID的实际信息。我使用用户表作为父项,因为我可以100%确定用户将出现在该表中,即使它们不在其他表中。我用这个查询得到了合适的数量!

+0

我不确定你的数据库设计是否合理。也许它有,但它看起来不像。 – 2011-04-13 06:30:36

+0

它非常有意义。用户发布挑战提示。该提示被发送到“提示”表,并且包含海报的user_id等。其他用户可以对该提示发表评论,这些提示会发送到“评论”表并且还包含user_id。最后,用户可以对提示进行投票,他们会保存在“投票”表中,并且还包含user_id。这是做到这一点的唯一方法,并能够跟踪谁发布/做什么。我需要确定一个用户是否投了票,或发布了一条提示或评论,以便我可以允许或不允许他们更改他们的显示名称。 – HaLo2FrEeEk 2011-04-13 06:53:23

+0

你得到0,0,0而不是0,0,3的原因是你的基表是'tips',它没有user_id,所以你用'votes'用'user_id'连接它。首先,所有的行都将从'tips'中获得,然后如果你与其他表一起'LEFT JOIN'连接。 MySql将查找每个拥有'votes'的user_id,然后加入它。然后,所有在'LEFT table or tips'中没有的user_id将被排除以从'votes'中得到,这就是为什么你不能在'votes'中得到user_id的原因。此外,使用DISTINCT时会出现问题,因为列中每个相等值的结果都会计为1. – ace 2011-04-13 09:29:19

回答

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上遇到了与您相同的查询问题,因此我最终收到了此查询。

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

+0

我只需要知道用户是否已投票或发布了提示或评论。如果其中任何一个为真,那么计数应该大于0.检查第一篇文章中的编辑。所有三个表中有两列相同:user_id和tip_id,因为评论和投票都与提示本身相关联。基本上,如果三个表中的任何一个包含user_id =#的行,那么我应该得到大于0的数字,如果没有表中包含user_id =#的行,则计数应该为0. – HaLo2FrEeEk 2011-04-13 07:09:04

+0

我认为查询会显示你想要的结果。我将在查询中编辑字段名称以反映您的字段,并且将为ID添加WHERE子句。如果它仍然不是你想要的,如果我有时间的话,我会尝试做一个新的查询。 – ace 2011-04-13 07:31:20

+0

对不起,但我完全不理解你的查询。 FROM子句中选择的目的是什么?您将行选入需要表的子句中。当我尝试运行它时,出现各种错误。我只需要一个单一的号码作为回报。这个数字将是指定user_id提示,评论和投票数量的总和。如果用户提出了1个小费,没有评论和2个投票,那么计数将是3.如果他们提出了5个提示,2个评论,并没有投票,那么计数将是7,是否合理? – HaLo2FrEeEk 2011-04-13 07:41:40

相关问题