2014-03-30 80 views
-1

我在編寫查詢時遇到問題,可以在特定條件下查找唯一的計數/重複項。我試圖在同一時間從表中類似於這樣一來獲取計數:SQL記錄的複雜計數

|-P_key-|-----email-----|-act_no-|--Client--| 
| 1 | [email protected] | 1 | Jets | 
| 2 | [email protected] | 2 | Jets | 
| 3 | [email protected] | NULL | Jets | 
| 4 | [email protected] | 1 | Bills | 
| 5 | [email protected] | 2 | Bills | 
| 6 | [email protected] | 2 | Giants | 
| 7 | [email protected] | 2 | Giants | 
| 8 | [email protected] | 5 | Pats | 

我需要的是通過客戶端如下計數:

  1. 的總記錄爲每個客戶端計數與重複的電子郵件在不同客戶端做好記錄
  2. 計數去除的好記錄
  3. 計數與重複帳戶的客戶中沒有任何的去除與重複帳戶良好記錄
  4. 計數跨客戶端沒有任何的去除的良好記錄
  5. 計數與空白帳戶客戶端中沒有的去除

凡任何重複項後/刪除從總的行數。

因此,來自噴氣機客戶端的[email protected][email protected]被刪除/不是從項目之後的唯一電子郵件之後的好/好/好,因爲它們存在於其他客戶端上,因此留下1個電子郵件地址([email protected])來自噴氣機客戶端,該客戶端不存在於其他客戶端上。

此外,對於內部客戶端,對於巨人客戶端,acct_no 2是唯一的acct_no,所以我不想計算任一記錄,無論acct_no 2是否在其他客戶端上(請參閱acct_no是如何唯一的其他客戶)。而在跨客戶端查找acct_nos時,對於Jets客戶端,所有3個acct_no在客戶端中都是唯一的,但不跨所有客戶端(只有空值在所有客戶端中是唯一的)。因此,在3個噴氣機acct_no中,3個在客戶端內是好的,但在客戶端只有1個是好的。

的出來把我希望能實現是爲如下(雖然最終的數據並不一定需要擺動這樣):

|            | Jets | Bills | Giants | Pats | 
| Total emails        | 3 | 2 | 2 | 1 | 
| good after unique emails across clients  | 1 | 0 | 1 | 1 | 
| good after unique account_no across clients | 1 | 0 | 0 | 1 | 
| good after unique account_no within clients | 3 | 2 | 0 | 1 | 
| good after blank account_no within clients | 2 | 0 | 0 | 0 | 

OR

|  | tot unique emails | good emails  | etc... 
| Jets | 3    | 1    | 
|Bills | 2    | 0    | 
| Giants | 2    | 1    |  
| Pats | 1    | 1    | 

值得注意的還有,如果我想添加另一個層,而不是客戶端,例如客戶端中的代理計數,那麼它將在客戶端上向該組添加另一個字段,我將如何處理該問題?

我在想一個辦法就是使用其中不存在的語句,如:

SELECT COUNT(x.act_no) 
FROM x 
WHERE NOT EXISTS (SELECT 'x' FROM t WHERE t.act_no = x.act_no) 
AND x.client = 'Jets' 

不過,我希望能夠返回在一個查詢所有罪狀,而不是拼湊出來,如果可能的。

感謝您提前提供任何幫助!

+0

定義「之後」。請注意,id自動生成的事實不會保證順序 - 特別是如果以後使用新信息更新了行。最好考慮id的實際值是隨機的(沒有固有的值)。你的標準也有點不透明 - 到目前爲止你嘗試過什麼,以幫助我們看看你要做什麼? –

+0

感謝您的迴應,我已經更新了我的問題,並舉了一個我正在嘗試的例子,希望能夠在「之後」 – Yikes

回答

0

這可能是最明顯的,從多個選擇拼湊它:

DECLARE @tbl TABLE (id INT, email VARCHAR(256), act_no INT NULL, client VARCHAR(10)) 
INSERT INTO @tbl VALUES 
( 1 , '[email protected]' , 1 , 'Jets' ) 
,( 2 , '[email protected]' , 2 , 'Jets' ) 
,( 3 , '[email protected]' , NULL , 'Jets' ) 
,( 4 , '[email protected]' , 1 , 'Bills' ) 
,( 5 , '[email protected]' , 2 , 'Bills' ) 
,( 6 , '[email protected]' , 2 , 'Giants') 
,( 7 , '[email protected]' , 2 , 'Giants') 
,( 8 , '[email protected]' , 5 , 'Pats' )  

SELECT 'Total emails',client, COUNT(*) 
    FROM @tbl 
GROUP BY client 

SELECT 'good after unique emails across clients',client, COUNT(*) 
    FROM @tbl a 
WHERE NOT EXISTS (SELECT 1 FROM @tbl b WHERE b.email=a.email AND b.client <> a.client) 
GROUP BY client 

SELECT 'good after unique account_no across clients',client, COUNT(*) 
    FROM @tbl a 
WHERE NOT EXISTS (SELECT 1 FROM @tbl b WHERE b.act_no=a.act_no AND b.client <> a.client) 
GROUP BY client 

SELECT 'good after unique account_no within clients',client, COUNT(*) 
    FROM @tbl a 
WHERE NOT EXISTS (SELECT 1 FROM @tbl b WHERE b.act_no=a.act_no AND b.client = a.client GROUP BY b.act_no,b.client HAVING COUNT(*) > 1) 
GROUP BY client 

然後,您可以UNION的結果。您也可以從客戶列表中左鍵單擊以確保顯示空值。

但是,您也可以相當簡潔地一次完成所有操作。請原諒別名過長。

;WITH cte AS (
     SELECT client 
      ,CASE WHEN NOT EXISTS (SELECT 1 FROM @tbl b WHERE b.email=a.email AND b.client <> a.client) THEN 1 ELSE 0 END [good after unique emails across clients] 
      ,CASE WHEN NOT EXISTS (SELECT 1 FROM @tbl b WHERE b.act_no=a.act_no AND b.client <> a.client) THEN 1 ELSE 0 END [good after unique account_no across clients] 
      ,CASE WHEN NOT EXISTS (SELECT 1 FROM @tbl b WHERE b.act_no=a.act_no AND b.client = a.client GROUP BY b.act_no,b.client HAVING COUNT(*) > 1) THEN 1 ELSE 0 END [good after unique account_no within clients] 
     FROM @tbl a 
    ) 
    SELECT client 
      ,COUNT(*) [Total emails] 
      ,SUM([good after unique emails across clients]) [good after unique emails across clients] 
      ,SUM([good after unique account_no across clients]) [good after unique account_no across clients] 
      ,SUM([good after unique account_no within clients]) [good after unique account_no within clients] 
     FROM cte a 
    GROUP BY client 

注意,我離開了斷「的客戶中空白account_no上後好」,我的身影,你可以很容易地添加。

0

不完全確定是否正確解釋聚合規則,但這是我想出的。這是一個垂直的結果,如果你希望它是水平的,你可以旋轉。

SELECT Client, result, CountType 
    FROM (SELECT  Client, COUNT(*) AS result, 'Total emails' AS CountType 
       FROM   ComplexCounting 
       GROUP BY Client 
       UNION 
       SELECT  Client, COUNT(*) AS result, 'good after unique emails across clients' AS CountType 
       FROM   ComplexCounting 
       WHERE  (NOT EXISTS 
              (SELECT  Id, email, act_no, Client 
               FROM   ComplexCounting AS c 
               WHERE  (Client <> ComplexCounting.Client) AND (email = ComplexCounting.email))) 
       GROUP BY Client 
       UNION 
       SELECT  Client, COUNT(*) AS result, 'good after unique account_no across clients' AS CountType 
       FROM   ComplexCounting 
       WHERE  (NOT EXISTS 
              (SELECT  Id, email, act_no, Client 
               FROM   ComplexCounting AS c 
               WHERE  (Client <> ComplexCounting.Client) AND (act_no = ComplexCounting.act_no))) 
       GROUP BY Client 
       UNION 
       SELECT  Client, COUNT(*) AS result, 'good after unique account_no within clients' AS CountType 
       FROM   ComplexCounting 
       WHERE  (NOT EXISTS 
              (SELECT  Id, email, act_no, Client 
               FROM   ComplexCounting AS c 
               WHERE  (Client = ComplexCounting.Client) AND (act_no = ComplexCounting.act_no) AND (Id <> ComplexCounting.Id))) 
       GROUP BY Client 
       UNION 
       SELECT  Client, COUNT(DISTINCT act_no) AS result, 'good after blank account_no within clients' AS CountType 
       FROM   ComplexCounting 
       WHERE  EXISTS 
              (SELECT  Id, email, act_no, Client 
               FROM   ComplexCounting AS c 
               WHERE  (act_no IS NULL) AND (Client = ComplexCounting.Client)) AND (act_no IS NOT NULL) 
       GROUP BY Client) AS Results 
    ORDER BY CountType