SQL Server:选择只有一个条件的ID

SQL Server:选择只有一个条件的ID,sql,sql-server,notin,Sql,Sql Server,Notin,我有一张患者表,上面有患者的病情等详细信息。我想从下表中选择患者,他们声称只有一种情况——“高血压”。示例患者B是预期输出。患者A不会被选中,因为他声称患有多种疾病 +----+---------+--------------+ | ID | ClaimID | Condition | +----+---------+--------------+ | A | 14234 | Hypertension | | A | 14234 | Diabetes | | A |

我有一张患者表,上面有患者的病情等详细信息。我想从下表中选择患者,他们声称只有一种情况——“高血压”。示例患者B是预期输出。患者A不会被选中,因为他声称患有多种疾病

+----+---------+--------------+
| ID | ClaimID |  Condition   |
+----+---------+--------------+
| A  |   14234 | Hypertension |
| A  |   14234 | Diabetes     |
| A  |   63947 | Diabetes     |
| B  |   23853 | Hypertension |
+----+---------+--------------+
我试着使用下面的“不在条件下”,但似乎没有帮助

SELECT ID, ClaimID, Condition 
FROM myTable 
WHERE Condition IN ('Hypertension') 
  AND Condition NOT IN ('Diabetes') 
一种方法不存在:

一种方法不存在:


你可以用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

你可以用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子句的方法

下面是一个使用Having子句的方法


或者你可以这样做:

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');

或者你可以这样做:

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 
这将返回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)
这会回来的

+----+---------+--------------+
| 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子句中,就可以了

我决定把我的答案修改成一个合适的答案

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

以下是一个简单的介绍:

SELECT 
    ID 
FROM 
    #PatientTable 
GROUP BY 
    ID 
HAVING
    ID = ID AND COUNT(*) = 1 
这将返回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)
这会回来的

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

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

    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

建议将最后一个案例更改为!=高血压,因此它可以处理其他继发性疾病,而不仅仅是糖尿病。建议将最后一个病例改为!=高血压,这样它就可以处理其他继发性疾病,而不仅仅是糖尿病。@JiggsJedi除了一个老一辈的人,只要能完成任务,你还能做什么;。但多亏了你,我想出了一个更好的解决办法。@JiggsJedi除了一个老手,他使用新旧语法,只要能完成任务,你还能做什么;。但多亏了你,我想出了一个更好的解决办法。