0

用户表:

  • user_id(每个用户不同)
  • source_id(用户可能有相同的来源)

规则表:

  • white_rules
  • black_rules
  • 一般规则

这些表看起来都一样,并且有:

  • victim_id(与 users 表中的 user_id 相关)。
  • rule_id(与不同的表相关联,这在此处并不重要)

我需要的是每个source_id 提取每种类型(白色,黑色,通用)的总规则量。

例子:

  • source_id: 5 ---> 共70条白规,共32条黑规,共21条一般规则
  • source_id: 7 ---> 共 2 条白色规则,共 0 条黑色规则,共 4 条通用规则

依此类推...对于用户表中列出的所有不同来源。

我尝试的是:

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;

但是我得到的结果表有错误(更高)的数字,而不是我期望得到的数字,所以我一定做错了什么:) 会感谢任何朝着正确方向的铰链。

4

1 回答 1

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

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

SQL Fiddle 示例

于 2013-02-27T17:25:16.307 回答