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
我在下面有一个 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