SQL查询:在WHERE子句

时间:2015-12-08 19:21:47

标签: sql sql-server where-clause

我目前正在开展一个项目,我有一份牙科病人名单,我应该展示所有患有两个特定程序代码的患者。这些患者必须有两个程序代码,而不是一个或另一个。起初我以为我可以通过在WHERE子句中使用基本的AND语句来实现这一点,就像这样。

SELECT [stuff]
FROM [this table]
WHERE ProcedureCode = 'ABC123' AND ProcedureCode = 'DEF456';

查询当然不会返回任何内容,因为代码是单独输入的,您不能同时同时使用过程1和过程2.

我尝试切换" AND"到"或"只是出于好奇。当然,我现在正在为只有一个代码或另一个代码的患者获得结果,但两者同时出现的患者也会出现,并且代码显示为单独的结果,如下所示:

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这样的患者,并且只包括像约翰史密斯这样的患者,他们都有两个程序代码。想法?

根据基督徒的答案添加信息

这是更新后的查询:

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个结果,但它们都是相同的代码,所以我们不想包含它们。即使约翰史密斯仍然有两个相同的代码,他的结果也包括两个代码,所以我们想让他和其他像他一样的病人。

另一个更新:

我刚刚了解到,我现在需要为相关患者提供一些基本的人口统计细节,因此我使用PatientInfo表加入了我的VisitInfo表。更新后的查询如下所示:

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是否会影响任何人的答案...

3 个答案:

答案 0 :(得分:3)

GL_COLOR_BUFFER_BIT

UPDATE 1:

As a patient can have multiple ´procedure codes´, this way will work better:

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 :(得分:1)

选择包含两个代码的记录,但使用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;

答案 2 :(得分:1)

有很多方法可以给这只特殊的猫皮肤涂抹 - 这是另一种:

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要求在连接两侧的表中存在匹配信息,所以这样的效果是仅保留与两个CTE中的信息匹配的访问,基于在这种情况下为PATIENTID的连接标准。

祝你好运。