SQL 查询:在 WHERE 子句中使用 AND/OR
SQL Query: Using AND/OR in the WHERE clause
我目前正在做一个项目,我有一个牙科患者列表,我应该显示所有在他们的个人资料中附加了两个特定程序代码的患者。这些患者必须有两个程序代码,而不是一个或另一个。起初我以为我可以通过在我的 WHERE 子句中使用一个基本的 AND 语句来完成这个,就像这样。
SELECT [stuff]
FROM [this table]
WHERE ProcedureCode = 'ABC123' AND ProcedureCode = 'DEF456';
当然returns没有查询,因为代码是单独输入的,您不能同时拥有程序 1 和程序 2。
出于好奇,我尝试将 "AND" 切换为 "OR"。当然,我现在正在为只有一种代码或另一种代码的患者获取结果,但同时出现两种代码的患者也出现了,代码显示为单独的结果,如下所示:
Patient ID Last Name First Name Code Visit Date
1111111 Doe Jane ABC123 11-21-2015
5555555 Smith John ABC123 12-08-2015
5555555 Smith John DEF456 12-08-2015
我的 SQL 最近很生疏。我正在尝试想出一种方法来过滤掉像 Jane Doe 这样的患者,只包括像 John Smith 这样具有两种程序代码的患者。想法?
根据基督徒的回答添加信息:
更新后的查询如下所示:
SELECT PatientID, LastName, FirstName, Code, VisitDate
FROM VisitInfo
WHERE PatientID IN
(
SELECT PatientID
FROM VisitInfo
WHERE Code = 'ABC123' OR Code = 'DEF456'
GROUP BY PatientID
HAVING COUNT(*) > 1
)
AND (Code = 'ABC123' OR Code = 'DEF456');
所以我仍然得到如下结果,其中一位患者只显示一个程序代码,但可能有多个实例:
Patient ID Last Name First Name Code Visit Date
1111111 Doe Jane ABC123 11-02-2015
1111111 Doe Jane ABC123 11-21-2015
5555555 Smith John ABC123 12-08-2015
5555555 Smith John DEF456 12-08-2015
5555555 Smith John ABC123 12-14-2015
9999999 Jones Mike DEF456 11-22-2015
9999999 Jones Mike DEF456 12-06-2015
尽管 Jane Doe 和 Mike Jones 有 2 个结果,但它们都是相同的代码,所以我们不想包括它们。即使 John Smith 仍然有 2 个相同的代码,他的结果也包括这两个代码,所以我们想保留他和其他像他一样的患者。
另一项更新:
我刚刚了解到我现在需要包含相关患者的一些基本人口统计信息,所以我加入了我的 VisitInfo table 和 PatientInfo table。更新后的查询如下所示:
SELECT v.PatientID, v.LastName, v.FirstName, v.Code, v.VisitDate, p.DateOfBirth, p.Gender, p.PrimaryPhone
FROM VisitInfo v JOIN PatientInfo p ON v.PatientID = p.PatientID
WHERE v.PatientID IN
(
SELECT PatientID
FROM VisitInfo
WHERE Code = 'ABC123' OR Code = 'DEF456'
GROUP BY PatientID
HAVING COUNT(*) > 1
)
AND (Code = 'ABC123' OR Code = 'DEF456');
我不确定新的 JOIN 是否会影响任何人的答案...
SELECT *
FROM TABLE
WHERE Patient_ID IN
(
SELECT Patient_ID
FROM TABLE
WHERE Code = 'ABC123' OR Code = 'DEF456'
GROUP BY Patient_ID
HAVING COUNT(*) = 2
)
AND (Code = 'ABC123' OR Code = 'DEF456')
更新 1:
由于一个病人可以有多个“程序代码”,这种方式会更好:
SELECT *
FROM TABLE T1
WHERE EXISTS (SELECT 1
FROM TABLE T2
WHERE T1.Patient_ID = T2.Patient_ID
AND T2.Code = 'ABC123')
AND EXISTS (SELECT 1
FROM TABLE T2
WHERE T1.Patient_ID = T2.Patient_ID
AND T2.Code = 'DEF456')
AND T1.Code IN ('ABC123','DEF456')
Select 包含两个代码的记录,但使用 COUNT OVER 来计算每个患者的不同代码。只保留那些记录有 2 个代码的患者,即具有 两个 个代码的患者。
select patient_id, last_name, first_name, code, visit_date
from
(
select mytable.*, count(distinct code) over (partition by patient_id) as cnt
from mytable
where code in ('ABC123','DEF456')
) data
where cnt = 2;
有很多方法可以给这只猫剥皮 - 这是另一种方法:
WITH ABC123 AS (SELECT DISTINCT PATIENTID
FROM VISITINFO
WHERE PROCEDURECODE = 'ABC123'),
DEF456 AS (SELECT DISTINCT PATIENTID
FROM VISITINFO
WHERE PROCEDURECODE = 'DEF456')
SELECT v.PATIENTID, v.LASTNAME, v.FIRSTNAME, v.PROCEDURECODE, v.VISITDATE,
p.DateOfBirth, p.Gender, p.PrimaryPhone
FROM VISITINFO v
INNER JOIN ABC123 a
ON a.PATIENTID = v.PATIENTID
INNER JOIN DEF456 d
ON d.PATIENTID = v.PATIENTID
INNER JOIN PatientInfo p
ON v.PatientID = p.PatientID
WHERE v.PROCEDURE_CODE IN ('ABC123', 'DEF456')
ORDER BY v.PATIENTID, v.VISITDATE, v.PROCEDURECODE;
我们在这里所做的是使用几个 CTE 来获取每位执行相关程序的患者的 PATIENTID。然后,我们从 VISITINFO 中的所有记录开始,并将这些记录与两个 CTE 进行内部连接。因为 INNER JOIN 要求匹配信息存在于连接两侧的表中,所以根据连接标准(在本例中为 PATIENTID),这具有仅保留与两个 CTE 中的信息匹配的访问的效果。
祝你好运。
我目前正在做一个项目,我有一个牙科患者列表,我应该显示所有在他们的个人资料中附加了两个特定程序代码的患者。这些患者必须有两个程序代码,而不是一个或另一个。起初我以为我可以通过在我的 WHERE 子句中使用一个基本的 AND 语句来完成这个,就像这样。
SELECT [stuff]
FROM [this table]
WHERE ProcedureCode = 'ABC123' AND ProcedureCode = 'DEF456';
当然returns没有查询,因为代码是单独输入的,您不能同时拥有程序 1 和程序 2。
出于好奇,我尝试将 "AND" 切换为 "OR"。当然,我现在正在为只有一种代码或另一种代码的患者获取结果,但同时出现两种代码的患者也出现了,代码显示为单独的结果,如下所示:
Patient ID Last Name First Name Code Visit Date
1111111 Doe Jane ABC123 11-21-2015
5555555 Smith John ABC123 12-08-2015
5555555 Smith John DEF456 12-08-2015
我的 SQL 最近很生疏。我正在尝试想出一种方法来过滤掉像 Jane Doe 这样的患者,只包括像 John Smith 这样具有两种程序代码的患者。想法?
根据基督徒的回答添加信息:
更新后的查询如下所示:
SELECT PatientID, LastName, FirstName, Code, VisitDate
FROM VisitInfo
WHERE PatientID IN
(
SELECT PatientID
FROM VisitInfo
WHERE Code = 'ABC123' OR Code = 'DEF456'
GROUP BY PatientID
HAVING COUNT(*) > 1
)
AND (Code = 'ABC123' OR Code = 'DEF456');
所以我仍然得到如下结果,其中一位患者只显示一个程序代码,但可能有多个实例:
Patient ID Last Name First Name Code Visit Date
1111111 Doe Jane ABC123 11-02-2015
1111111 Doe Jane ABC123 11-21-2015
5555555 Smith John ABC123 12-08-2015
5555555 Smith John DEF456 12-08-2015
5555555 Smith John ABC123 12-14-2015
9999999 Jones Mike DEF456 11-22-2015
9999999 Jones Mike DEF456 12-06-2015
尽管 Jane Doe 和 Mike Jones 有 2 个结果,但它们都是相同的代码,所以我们不想包括它们。即使 John Smith 仍然有 2 个相同的代码,他的结果也包括这两个代码,所以我们想保留他和其他像他一样的患者。
另一项更新:
我刚刚了解到我现在需要包含相关患者的一些基本人口统计信息,所以我加入了我的 VisitInfo table 和 PatientInfo table。更新后的查询如下所示:
SELECT v.PatientID, v.LastName, v.FirstName, v.Code, v.VisitDate, p.DateOfBirth, p.Gender, p.PrimaryPhone
FROM VisitInfo v JOIN PatientInfo p ON v.PatientID = p.PatientID
WHERE v.PatientID IN
(
SELECT PatientID
FROM VisitInfo
WHERE Code = 'ABC123' OR Code = 'DEF456'
GROUP BY PatientID
HAVING COUNT(*) > 1
)
AND (Code = 'ABC123' OR Code = 'DEF456');
我不确定新的 JOIN 是否会影响任何人的答案...
SELECT *
FROM TABLE
WHERE Patient_ID IN
(
SELECT Patient_ID
FROM TABLE
WHERE Code = 'ABC123' OR Code = 'DEF456'
GROUP BY Patient_ID
HAVING COUNT(*) = 2
)
AND (Code = 'ABC123' OR Code = 'DEF456')
更新 1:
由于一个病人可以有多个“程序代码”,这种方式会更好:
SELECT *
FROM TABLE T1
WHERE EXISTS (SELECT 1
FROM TABLE T2
WHERE T1.Patient_ID = T2.Patient_ID
AND T2.Code = 'ABC123')
AND EXISTS (SELECT 1
FROM TABLE T2
WHERE T1.Patient_ID = T2.Patient_ID
AND T2.Code = 'DEF456')
AND T1.Code IN ('ABC123','DEF456')
Select 包含两个代码的记录,但使用 COUNT OVER 来计算每个患者的不同代码。只保留那些记录有 2 个代码的患者,即具有 两个 个代码的患者。
select patient_id, last_name, first_name, code, visit_date
from
(
select mytable.*, count(distinct code) over (partition by patient_id) as cnt
from mytable
where code in ('ABC123','DEF456')
) data
where cnt = 2;
有很多方法可以给这只猫剥皮 - 这是另一种方法:
WITH ABC123 AS (SELECT DISTINCT PATIENTID
FROM VISITINFO
WHERE PROCEDURECODE = 'ABC123'),
DEF456 AS (SELECT DISTINCT PATIENTID
FROM VISITINFO
WHERE PROCEDURECODE = 'DEF456')
SELECT v.PATIENTID, v.LASTNAME, v.FIRSTNAME, v.PROCEDURECODE, v.VISITDATE,
p.DateOfBirth, p.Gender, p.PrimaryPhone
FROM VISITINFO v
INNER JOIN ABC123 a
ON a.PATIENTID = v.PATIENTID
INNER JOIN DEF456 d
ON d.PATIENTID = v.PATIENTID
INNER JOIN PatientInfo p
ON v.PatientID = p.PatientID
WHERE v.PROCEDURE_CODE IN ('ABC123', 'DEF456')
ORDER BY v.PATIENTID, v.VISITDATE, v.PROCEDURECODE;
我们在这里所做的是使用几个 CTE 来获取每位执行相关程序的患者的 PATIENTID。然后,我们从 VISITINFO 中的所有记录开始,并将这些记录与两个 CTE 进行内部连接。因为 INNER JOIN 要求匹配信息存在于连接两侧的表中,所以根据连接标准(在本例中为 PATIENTID),这具有仅保留与两个 CTE 中的信息匹配的访问的效果。
祝你好运。