按两个列值的计数过滤行

时间:2015-07-28 07:37:17

标签: sql sql-server

我有以下表格:

Card(
  MembershipNumber,
  EmbossLine,
  status,
  EmbossName
)

包含样本数据

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

我想要检索行,以便只显示那些行count MembershipNumber > 1且计数为status='E0' > 1的行。

例如查询应返回以下结果

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

我有查询用MembershipNumber计数过滤它,但无法弄清楚如何按status ='E0'过滤。这是迄今为止的查询

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

4 个答案:

答案 0 :(得分:2)

您只需在子查询中添加WHERE status = 'E0'

SQL Fiddle归功于Raging Bull的小提琴

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

答案 1 :(得分:1)

你可以这样做:

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'

结果:

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

SQL Fiddle

中的示例结果

答案 2 :(得分:0)

尝试:

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;

答案 3 :(得分:0)

你可以试试这个:

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

我们的想法是添加第二个counter,而不是COUNT函数来使用SUM函数来仅计算具有[status] = 'E0'的行。然后,在where子句中,我们将通过两个计数器和[status] = 'E0'进行过滤。