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 中的信息匹配的访问的效果。

祝你好运。