用户表:
规则表:
这些表看起来都一样,并且有:
我需要的是每个source_id提取每种类型的总规则数量(白色,黑色,一般)。
示例:
等等...对于用户表中列出的所有不同来源。
我试过的是:SELECT source_id,
count(w.victim_id) as total_white,
count(b.victim_id) as total_black,
count(g.victim_id) as total_general
from users
LEFT JOIN white_rules as w ON (user_id=w.victim_id)
LEFT JOIN black_rules as b ON (user_id=b.victim_id)
LEFT JOIN general_rules as g ON (user_id=g.victim_id)
where deleted='f' and source is not null
group by source;
但是我获得的结果表的数字错误(更高)超出了我的预期, 所以我一定做错了:) 我会欣赏正确方向的任何铰链。
答案 0 :(得分:0)
您需要在子查询中进行计数,或计数不同,因为您的多个1对多关系导致交叉连接。我不知道你的数据,但想象一下这个场景:
用户:强>
User_ID | Source_ID
--------+--------------
1 | 1
<强> White_Rules 强>
Victim_ID | Rule_ID
----------+-------------
1 | 1
1 | 2
<强> Black_Rules 强>
Victim_ID | Rule_ID
----------+-------------
1 | 3
1 | 4
如果你跑
SELECT Users.User_ID,
Users.Source_ID,
White_Rules.Rule_ID AS WhiteRuleID,
Black_Rules.Rule_ID AS BlackRuleID
FROM Users
LEFT JOIN White_Rules
ON White_Rules.Victim_ID = Users.User_ID
LEFT JOIN Black_Rules
ON Black_Rules.Victim_ID = Users.User_ID
您将获得White_Rules.Rule_ID
和Black_Rules.Rule_ID
的所有组合:
User_ID | Source_ID | WhiteRuleID | BlackRuleID
--------+-----------+-------------+-------------
1 | 1 | 1 | 3
1 | 1 | 2 | 4
1 | 1 | 1 | 3
1 | 1 | 2 | 4
因此计算结果将返回4条白色规则和4条黑色规则,即使每条规则只有2条。
如果您将查询更改为此内容,则应获得所需的结果:
SELECT Users.Source_ID,
SUM(COALESCE(w.TotalWhite, 0)) AS TotalWhite,
SUM(COALESCE(b.TotalBlack, 0)) AS TotalBlack,
SUM(COALESCE(g.TotalGeneral, 0)) AS TotalGeneral
FROM Users
LEFT JOIN
( SELECT Victim_ID, COUNT(*) AS TotalWhite
FROM White_Rules
GROUP BY Victim_ID
) w
ON w.Victim_ID = Users.User_ID
LEFT JOIN
( SELECT Victim_ID, COUNT(*) AS TotalBlack
FROM Black_Rules
GROUP BY Victim_ID
) b
ON b.Victim_ID = Users.User_ID
LEFT JOIN
( SELECT Victim_ID, COUNT(*) AS TotalGeneral
FROM General_Rules
GROUP BY Victim_ID
) g
ON g.Victim_ID = Users.User_ID
WHERE Deleted = 'f'
AND Source IS NOT NULL
GROUP BY Users.Source_ID
<强> Example on SQL Fiddle 强>
另一种选择是:
SELECT Users.Source_ID,
COUNT(Rules.TotalWhite) AS TotalWhite,
COUNT(Rules.TotalBlack) AS TotalBlack,
COUNT(Rules.TotalGeneral) AS TotalGeneral
FROM Users
LEFT JOIN
( SELECT Victim_ID, 1 AS TotalWhite, NULL AS TotalBlack, NULL AS TotalGeneral
FROM White_Rules
UNION ALL
SELECT Victim_ID, NULL AS TotalWhite, 1 AS TotalBlack, NULL AS TotalGeneral
FROM Black_Rules
UNION ALL
SELECT Victim_ID, NULL AS TotalWhite, NULL AS TotalBlack, 1 AS TotalGeneral
FROM General_Rules
) Rules
ON Rules.Victim_ID = Users.User_ID
WHERE Deleted = 'f'
AND Source IS NOT NULL
GROUP BY Users.Source_ID
<强> Example on SQL Fiddle 强>