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
我有一位患者 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