2015-07-28 12 views
5

Ho seguente tabella:Filtro righe per conteggio di due colonna Valori

Card(
    MembershipNumber, 
    EmbossLine, 
    status, 
    EmbossName 
) 

con dati di esempio

(0009,0321,'E0','Finn') 
(0009,0322,'E1','Finn') 
(0004,0356,'E0','Mary') 
(0004,0398,'E0','Mary') 
(0004,0382,'E1','Mary') 

voglio recuperare le righe in modo che solo le righe dovrebbero apparire che hanno count di MembershipNumber > 1 E il conteggio di status='E0' > 1.

Per esempio La query deve restituire seguente risultato

(0004,0356,'E0','Mary') 
(0004,0398,'E0','Mary') 

ho la query per il filtraggio con conteggio MembershipNumber ma riesco a capire come filtrare per stato = 'E0'. Ecco la query finora

SELECT * 
FROM (SELECT *, 
       Count(MembershipNumber)OVER(partition BY EmbossName) AS cnt 
     FROM card) A 
WHERE cnt > 1 
+0

Aggiungi 'WHERE stato = 'E0'' nel subquery. –

+0

Ho fatto ma poi restituisce tutti quelli che hanno stato = 'E0'. In caso del mio esempio restituirà anche '(0009,0321, 'E0', 'Finn')'. Il che non è richiesto – Nuke

+0

Sei sicuro, perché funziona bene sulla mia macchina: 'SELECT * FROM (SELECT *, Count (MembershipNumber) OVER (partizione EmbossName) AS cnt dalla scheda \t \t WHERE stato = 'E0 ' \t \t) A DOVE cnt> 1 ' –

risposta

2

Si può solo aggiungere WHERE status = 'E0' all'interno del vostro subquery:

SQL Fiddle (credito per Toro scatenato per il violino)

SELECT * 
FROM (
    SELECT *, 
     COUNT(MembershipNumber) OVER(PARTITION BY EmbossName) AS cnt 
    FROM card 
    WHERE status = 'E0' 
)A 
WHERE cnt > 1 
0

prova:

WITH cnt AS (
    SELECT MembershipNumber, status 
     FROM Card 
     WHERE status = 'E0' 
     GROUP BY MembershipNumber, status 
     HAVING COUNT(MembershipNumber) > 1 AND COUNT(status) > 1 
) 
SELECT c.* 
    FROM Card c 
    INNER JOIN cnt 
     ON c.MembershipNumber = cnt.MembershipNumber 
      AND c.status = cnt.status; 
1

si può fare in questo modo:

select t1.* 
from card t1 left join 
    (select EmbossName 
    from card 
    where [status]='E0' 
    group by EmbossName,[status] 
having count(MembershipNumber)>1) t2 on t1.EmbossName=t2.EmbossName 
where t2.EmbossName is not null and [status]='E0' 

Risultato:

MembershipNumber EmbossLine status EmbossName 
--------------------------------------------------- 
4     356   E0  Mary 
4     398   E0  Mary 

risultato del campione nel SQL Fiddle

0.123.
0

si può provare questo:

DECLARE @DataSource TABLE 
(
    [MembershipNumber] SMALLINT 
    ,[EmbossLine] SMALLINT 
    ,[status] CHAR(2) 
    ,[EmbossName] VARCHAR(8) 
); 

INSERT INTO @DataSource ([MembershipNumber], [EmbossLine], [status], [EmbossName]) 
VALUES (0009,0321,'E0','Finn') 
     ,(0009,0322,'E1','Finn') 
     ,(0004,0356,'E0','Mary') 
     ,(0004,0398,'E0','Mary') 
     ,(0004,0382,'E1','Mary'); 

SELECT [MembershipNumber] 
     ,[EmbossLine] 
     ,[status] 
     ,[EmbossName] 
FROM 
(
    SELECT * 
      ,COUNT([MembershipNumber]) OVER (PARTITION BY [EmbossName]) AS cnt1 
      ,SUM(IIF([status] = 'E0' , 1, 0)) OVER (PARTITION BY [EmbossName]) AS cnt2 
    FROM @DataSource 
) DS 
WHERE cnt1 > 1 
    AND cnt2 > 1 
    AND [status] = 'E0'; 

enter image description here

L'idea è quella di aggiungere un secondo counter, ma invece di COUNT funzione da utilizzare SUM funzione per contare solo le righe che hanno [status] = 'E0'. Quindi, nella clausola where, filtriamo i due contatori e [status] = 'E0'.

Problemi correlati