Question

I have a patient database and I am trying to extract a list of patients that have a particular diagnosis and have a specific procedure performed. The problem is I only want to retrieve a list of patients who have a procedure done at least twice. Here is some sample data.

Table Name = "ClinicalData"

PatientID        Diagnosis           Procedure               ProcedureDate
--------------------------------------------------------------------------
1                Laceration          Stitches                2/12/2013
1                Fracture            Cast                    2/12/2013
1                Fracture            Cast                    2/13/2013
2                Lung-Cancer         Chemotherapy            4/07/2013
2                Lung-Cancer         Radiation               3/02/2013
2                Liver-Cancer        Chemotherapy            6/03/2013
3                Diabetes            Hemoglobin-A1C-Check    3/12/2013
3                Diabetes            Hemoglobin-A1C-Check    7/11/2013

SELECT 
   PatientID,
   Min(ProcedureDate) 
FROM 
   ClinicalData cd1
      INNER JOIN ClinicalData cd2 ON cd1.PatientID = PatientID
         AND Diagnosis IN ('Laceration', 'Lung-Cancer','Diabetes')
WHERE
   Procedure IN ('Stitches', 'Cast', 'Hemoglobin-A1C-Check')
GROUP BY
   PatientID

What I want to obtain is a list of all patients who have have a diagnosis of (Laceration, Lung-Cancer, or Diabetes) who have had one of the listed procedures ('Stitches', 'Cast', 'Hemoglobin-A1C-Check') at least twice and their earliest Visit Date. So in the above example I would like to obtain ...

PatientID       ProcedureDate
------------------------------
3               3/12/2013

Because I am only interested in finding patients with Laceration, Lung-Cancer, and Diabetes notice that Patient 1 is not included since his/her diagnosis is Fracture. The problem I am having is how to get those patients who match the diagnosis and procedures I am looking for and have had a given procedure done at least twice. I have tried doing another self join and then modifying the WHERE clause to search for a second instance of a procedure but when I try and run the query is just keep going ... and going ... I must have something wrong. Here is the SQL I tried.

SELECT 
   PatientID,
   Min(ProcedureDate) 
FROM 
   ClinicalData cd1
      INNER JOIN ClinicalData cd2 ON cd1.PatientID = cd2.PatientID
         AND cd2.Diagnosis IN ('Laceration', 'Lung-Cancer','Diabetes')
      INNER JOIN ClinicalData cd3 ON cd1.PatientID = cd3.PatientID
WHERE
   cd1.Procedure IN ('Stitches', 'Cast', 'Hemoglobin-A1C-Check')
   AND cd3.Procedure IN ('Stitches', 'Cast', 'Hemoglobin-A1C-Check')
GROUP BY
   PatientID

I tried to put together a short example. In real life the diagnosis and procedures are represented as codes and are not hard coded in the query. They are done via lookup tables, for example . WHERE Procedure IN (SELECT Procedure From ProcedureList)

Was it helpful?

Solution

SELECT 
   PatientID,
   Min(ProcedureDate) 
FROM 
   ClinicalData cd1
WHERE
   [Procedure] IN ('Stitches', 'Cast', 'Hemoglobin-A1C-Check')
         AND Diagnosis IN ('Laceration', 'Lung-Cancer','Diabetes')
GROUP BY
   PatientID, Diagnosis, [Procedure]
Having Count(*) > 1

OTHER TIPS

why don't you try something like this, it should be what you want:

SELECT patientid, MIN(proceduredate)
FROM @clinicaldata
WHERE diagnosis IN ('laceration', 'lung-cancer', 'diabetes') AND procedure IN ('stitches',      'cast', 'hemoglobin-a1c-check')
GROUP BY patientid
HAVING COUNT(*) > 1

even if you need to join to other tables there should be no need to self join in a query like this. it should suffice to use having to get the count for how many times the patient has visited and then just ensuring that in the where clause you specify which diagnoses and procedures you want to include should be sufficient.

Assuming SQL Server 2005+, you can do this:

;WITH CTE AS
(
    SELECT  PatientID,
            [Procedure],
            MIN(ProcedureDate) ProcedureDate
    FROM ClinicalData cd1
    WHERE NOT EXISTS(SELECT 1 FROM ClinicalData
                     WHERE Diagnosis NOT IN ('Laceration', 'Lung-Cancer','Diabetes')
                     AND PatientID = cd1.PatientID)
    GROUP BY PatientID,
             [Procedure]
    HAVING COUNT(*) >= 2
)
SELECT  PatientID,
        MIN(ProcedureDate) ProcedureDate
FROM CTE
GROUP BY PatientID

The results are:

╔═══════════╦════════════════╗
║ PATIENTID ║ PROCEDUREDATE  ║
╠═══════════╬════════════════╣
║         3 ║ March, 12 2013 ║
╚═══════════╩════════════════╝

And here is a sqlfiddle with a demo.

You can try with something like this:

SELECT 
   PatientID,
   Min(ProcedureDate),
   Distinct(Procedure),
   Count(Diagnosis) as DiagnosisTotal
FROM 
   ClinicalData cd1
      INNER JOIN ClinicalData cd2 ON cd1.PatientID = PatientID
         AND Diagnosis IN ('Laceration', 'Lung-Cancer','Diabetes')
WHERE
   Procedure IN ('Stitches', 'Cast', 'Hemoglobin-A1C-Check')
       AND DiagnosisTotal > 1
GROUP BY
   PatientID
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top