Microsoft SQL Server 2014 - 无法通过自联接阻止笛卡尔结果

Microsoft SQL Server 2014 - Cannot prevent Cartesian results with Self Join

我在下面有一个 table - table 填充了客户密钥和角色。每个客户密钥都可以有多个与之关联的不同角色,我希望能够识别具有特定角色列表的客户密钥。例如,我希望能够识别所有具有角色 ("A"、"B"、"C") 的帐户。

+--------------+------------+----+
| customer_key | sales_role |    |
+--------------+------------+----+
|          123 | A          |    |
|          123 | B          |    |
|          123 | C          |    |
|          456 | A          |    |
|          456 | B          |    |
|          789 | A          |    |
|          789 | B          |    |
|          789 | C          |    |
|          987 | A          |    |
|          987 | B          |    |
|          987 | C          |    |
|          987 | D          |    |
|          654 | E          |    |
|          654 | F          |    |
|              | Te<br />st | 45 |
+--------------+------------+----+

我已成功使用以下查询来识别最多两个角色的帐户:

SELECT 
c.customer_key
,COUNT(c.sales_role) as 'count'
FROM 
    table a
    INNER JOIN  table b ON a.customer_key=b.customer_key    
    RIGHT JOIN  table c ON c.customer_key=a.customer_key
WHERE 
    a.sales_role  = 'A' AND
    b.sales_role  = 'B' 
GROUP BY c.customer_key
HAVING 
    COUNT(c.sales_role) = 2

上面的查询会给我 customer_key '456'。

但是,当我尝试添加更多联接以使用以下查询识别更多角色时,我得到了笛卡尔积。

SELECT 
e.customer_key
,COUNT(e.sales_role) as 'count'
FROM 
    table a
    INNER JOIN  table b ON a.customer_key=b.customer_key    
    INNER JOIN  table c ON a.customer_key=c.customer_key
    INNER JOIN  table d ON a.customer_key=d.customer_key
    RIGHT JOIN  table e ON e.customer_key=a.customer_key
WHERE 
    a.sales_role  = 'A' 
    AND b.sales_role  = 'B'    
    AND c.sales_role  = 'C' 


GROUP BY e.customer_key
HAVING 
    COUNT(e.sales_role) = 3

我不确定在这里还能尝试什么,如有任何帮助,我们将不胜感激。

此查询不需要多个连接,应该可以满足您的需要:

SELECT 
a.customer_key
,COUNT(DISTINCT a.sales_role) as 'count'
FROM table a
WHERE a.sales_role  IN ('A', 'B')
GROUP BY a.customer_key
HAVING 
    COUNT(DISTINCT a.sales_role) = 2

当您需要检查 A、B 和 C 时,根据需要更改 IN 和 HAVING 语句。

请注意,如果您需要 return 仅具有您要查找的值的记录,您将需要修改查询以测试是否存在其他角色,并将这些角色排除在外。可以这样做:

SELECT 
    a.customer_key
    ,COUNT(DISTINCT a.sales_role) as 'count'
FROM table a
WHERE a.sales_role  IN ('A', 'B')
AND NOT EXISTS (
    SELECT *
    FROM table b
    WHERE b.customer_key = a.customer_key
    AND b.sales_role NOT IN ('A', 'B')
    )
GROUP BY a.customer_key
HAVING 
    COUNT(DISTINCT a.sales_role) = 2

您可以调整下面的查询,统计您要统计的组合sale_roles,试一试。

SELECT Customer_Key
    , SUM(CASE Sales_Role WHEN 'A' THEN 1
                         WHEN 'B' THEN 1
                         WHEN 'C' THEN 1
                          ELSE 0 END) CntABC
    , SUM(CASE Sales_Role WHEN 'A' THEN 1
                         WHEN 'B' THEN 1            
                          ELSE 0 END) CntAB
    , SUM(CASE Sales_Role WHEN 'E' THEN 1   
            ELSE 0 END) CntE
FROM table
GROUP BY Customer_Key