SQL 服务器:SELECT ID 只有一个条件

SQL Server : SELECT ID having only a single condition

我有一位患者 table,其中包含患者的病情等详细信息。从下面 table 我想 select 患者,索赔只有一个条件 - 'Hypertension'。示例患者 B 是预期的输出。患者 A 将不会 selected,因为他声称有多种情况。

+----+---------+--------------+
| ID | ClaimID |  Condition   |
+----+---------+--------------+
| A  |   14234 | Hypertension |
| A  |   14234 | Diabetes     |
| A  |   63947 | Diabetes     |
| B  |   23853 | Hypertension |
+----+---------+--------------+

我尝试使用下面的 NOT IN 条件,但似乎没有帮助

SELECT ID, ClaimID, Condition 
FROM myTable 
WHERE Condition IN ('Hypertension') 
  AND Condition NOT IN ('Diabetes') 

一种方法使用 not exists:

select t.*
from mytable t
where t.condition = 'Hypertension' and
      not exists (select 1
                  from mytable t2
                  where t2.id = t.id and t2.condition <> t.condition
                 );

你可以用 CTE 做到这一点。

我为这个 CTE 设置了两个参数,一个是您要查找的条件,另一个是要查找的组合条件的最大数量(在您的情况下为 1)。

DECLARE @myTable TABLE (Id VARCHAR(1), ClaimID INT, Condition VARCHAR(100))
INSERT INTO @myTable (Id, ClaimID, Condition)
SELECT 'A',14234,'Hypertension' UNION ALL
SELECT 'A',14234,'Diabetes' UNION ALL
SELECT 'A',63947,'Diabetes' UNION ALL
SELECT 'B',23853,'Hypertension'

DECLARE @Condition VARCHAR(100)
DECLARE @MaxConditions TINYINT

SET @Condition='Hypertension'
SET @MaxConditions=1

; WITH CTE AS
(
    SELECT *, COUNT(2) OVER(PARTITION BY ClaimID) AS CN
    FROM @myTable T1
    WHERE EXISTS (SELECT 1 FROM @myTable T2 WHERE T1.ClaimID=T2.ClaimID AND T2.Condition=@Condition)
)

SELECT *
FROM CTE
WHERE CN<=@MaxConditions

如果您不关心这些问题,而只想让所有 ClaimID 都具有一个条件,而不管它是哪个条件,请使用此选项。

DECLARE @myTable TABLE (Id VARCHAR(1), ClaimID INT, Condition VARCHAR(100))
INSERT INTO @myTable (Id, ClaimID, Condition)
SELECT 'A',14234,'Hypertension' UNION ALL
SELECT 'A',14234,'Diabetes' UNION ALL
SELECT 'A',63947,'Diabetes' UNION ALL
SELECT 'B',23853,'Hypertension'

DECLARE @MaxConditions TINYINT

SET @MaxConditions=1

; WITH CTE AS
(
    SELECT *, COUNT(2) OVER(PARTITION BY ClaimID) AS CN
    FROM @myTable T1
)

SELECT *
FROM CTE
WHERE CN<=@MaxConditions

这是使用 Having 子句

的一种方法
SELECT t.*
FROM   mytable t
WHERE  EXISTS (SELECT 1
               FROM   mytable t2
               WHERE  t2.id = t.id
               HAVING Count(CASE WHEN condition = 'Hypertension' THEN 1 END) > 0
                      AND Count(CASE WHEN condition != 'Hypertension' THEN 1 END) = 0) 

或者你可以这样做:

select 
    id,
    claim_id,
    condition
from 
    patient
where 
    id in
    (
        select
            id
        from
            patient
        group by
            id having count (distinct condition) = 1
    );

结果:

id claim_id    condition
-- ----------- ----------------
B        23853 Hypertension

(1 rows affected)

设置:

create table patient
(
    id         varchar(1),
    claim_id   int,
    condition  varchar(16)
);

insert into patient (id, claim_id, condition) values ('A', 14234, 'Hypertension');
insert into patient (id, claim_id, condition) values ('A', 14234, 'Diabetes');
insert into patient (id, claim_id, condition) values ('A', 63947, 'Diabetes');
insert into patient (id, claim_id, condition) values ('B', 23853, 'Hypertension');

我决定将我的答案修改为合适的答案。

您问题的一个简单解决方案是计算行数而不是 ID 值(因为它不是整数)。

简单介绍一下:

SELECT 
    ID 
FROM 
    #PatientTable 
GROUP BY 
    ID 
HAVING
    ID = ID AND COUNT(*) = 1 

这将 Return ID B

+----+
| ID |
+----+
| B  |
+----+

当然,这还不够,因为您可能处理大量数据并且需要更多过滤。

所以,我们将把它用作子查询。

将它用作子查询很简单:

SELECT
    ID, 
    ClaimID, 
    Condition
FROM 
    #PatientTable
WHERE 
    ID = (SELECT ID AS NumberOfClaims FROM #PatientTable GROUP BY ID HAVING ID = ID AND COUNT(*) = 1)

这将 return

+----+---------+--------------+
| ID | ClaimID |  Condition   |
+----+---------+--------------+
| B  |   23853 | Hypertension |
+----+---------+--------------+

到目前为止一切顺利,但我们可能会面临另一个问题。假设您有来自多名患者的多项索赔,按原样使用此查询只会显示一名患者。要显示所有患者,我们需要在 WHERE 子句

下使用 IN 而不是 =
WHERE 
    ID IN (SELECT ID AS NumberOfClaims FROM #PatientTable GROUP BY ID HAVING ID = ID AND COUNT(*) = 1)

这将列出属于这种情况的所有患者。

如果您需要更多条件进行过滤,只需将它们添加到 WHERE 子句中即可。

还有其他几种方法可以做到这一点:

    declare @TableA  table(Id char,
                           ClaimId int,
                           Condition varchar(250));
    insert into @TableA (id, claimid, condition)
                values ('A', 14234, 'Hypertension'),
                       ('A', 14234, 'Diabetes'),
                       ('A', 63947, 'Diabetes'),
                       ('B', 23853, 'Hypertension')       


    select id, claimid, condition
    from @TableA a
    where not exists(select id
                     from @TableA b
                     where a.id = b.id
                     group by b.id
                     having count(b.id) > 1)

    OR

    ;with cte as
   (
     select id, claimid, condition
     from @TableA
   )
   ,
   cte2 as
   (
     Select id, count(Id) as counts
     from cte
     group by id
     having count(id) < 2       
    )

   Select cte.id, claimid, condition
   From cte
   inner join
   cte2
   on cte.id = cte2.id
SELECT id, sum(ct)
FROM (SELECT customer_id, CASE WHEN category = 'X' THEN 0 else 1 
end ct
FROM MASTER_TABLE
) AS t1
GROUP BY id
HAVING sum(ct) = 0

id 的 sum(ct) 大于 1,将有多个条件

使用连接而不是子查询。联接在性能上总是更好。您可以使用以下查询。

SELECT T1.id, T1.claimid, T1.Condition
FROM mytable T1
INNER JOIN 
(
    select id, count(Condition)  counter
    from mytable 
    group by id HAVING COUNT(DISTINCT CONDITION)=1
) T2 ON T1.ID=T2.ID
WHERE  T2.counter=1