2017-04-21 31 views
0

我有以下表 - 表填充客戶鍵和角色。每個客戶密鑰可以有多個與之相關的不同角色,並且我希望能夠識別具有特定角色列表的客戶密鑰。例如,我希望能夠與角色(「A」,「B」,「C」),以確定所有的帳戶。的Microsoft SQL Server 2014 - 無法阻止笛卡爾結果與自加入

+--------------+------------+----+ 
| 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 

我不知道還有什麼要嘗試在這裏,任何幫助將不勝感激。

回答

2

這個查詢,不需要多個連接,應該做你需要的東西:

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,根據需要更改中,以及報表。

請注意,如果你需要返回,只有你正在尋找的值的記錄,您將需要修改查詢來測試其他角色的存在,並排除。這是可以做到這樣的:

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 
+0

非常感謝您的先生,這似乎已經成功了。你介意解釋查詢中的NOT EXISTS部分嗎? – raidboss

+0

當然。一旦你已經確定了一個具體的customer_key值你所尋找的銷售角色匹配,不包括其中的查詢存在外觀,看是否有分配給客戶任何其他銷售角色。如果在該查詢中找不到任何內容,則NOT EXISTS()返回TRUE;如果存在與該查詢匹配的任何行,則返回FALSE。你可以這樣讀:「如果這個查詢沒有返回任何行,則報告TRUE,否則報告FALSE」。 –

+0

非常詳細的解釋,再次感謝:) – raidboss

0

您可以調整下面的查詢,統計要計算組合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