April 12, 2007 at 2:04 pm
I have puzzled over this one for a while, and can't seem to get it.
I have a table of patients, doctor's appointments, and doctor's names.
DECLARE @Appt TABLE (
PATIENT decimal(12,0),
SER_DT datetime,
PROV varchar(30))
INSERT INTO @Appt VALUES (1, '2007-03-01', 'Smith')
INSERT INTO @Appt VALUES (1, '2007-03-02', 'Smith')
INSERT INTO @Appt VALUES (1, '2007-03-03', 'Smith')
INSERT INTO @Appt VALUES (1, '2007-03-04', 'Jones')
INSERT INTO @Appt VALUES (2, '2007-03-01', 'Doe')
INSERT INTO @Appt VALUES (2, '2007-03-04', 'Doe')
INSERT INTO @Appt VALUES (2, '2007-03-08', 'Jones')
INSERT INTO @Appt VALUES (2, '2007-03-10', 'Jones')
INSERT INTO @Appt VALUES (2, '2007-03-11', 'Jones')
INSERT INTO @Appt VALUES (2, '2007-03-12', 'Doe')
INSERT INTO @Appt VALUES (2, '2007-03-13', 'Doe')
INSERT INTO @Appt VALUES (2, '2007-03-14', 'Doe')
INSERT INTO @Appt VALUES (3, '2007-03-01', 'Jones')
INSERT INTO @Appt VALUES (3, '2007-03-07', 'Doe')
INSERT INTO @Appt VALUES (3, '2007-03-14', 'Jones')
I want to select the first occurance of patient and doctor for each patient who has seen the same doctor three times in a row. In my sample data above, I should select patient #1 and Dr. Smith, patient #2 and Dr. Jones (but not Dr. Doe since #2 saw Jones three consecutive times first), and no one for patient #3.
I was able to implement a solution using a cursor, but I know there's a set-based approach to accomplish this. Any ideas? Thanks.
Update: Sorry for the syntax errors, I had to cut down the production code quite a bit to make it fit here, and I did it poorly. I've fixed it now (I think).
April 12, 2007 at 3:20 pm
-- Prepare sample data
DECLARE @Appt TABLE (Patient INT, Ser_DT DATETIME, Prov VARCHAR(30))
INSERT @Appt
SELECT 1, '2007-03-01', 'Smith' UNION ALL
SELECT 1, '2007-03-02', 'Smith' UNION ALL
SELECT 1, '2007-03-03', 'Smith' UNION ALL
SELECT 1, '2007-03-04', 'Jones' UNION ALL
SELECT 7, '2007-03-01', 'Doe' UNION ALL
SELECT 7, '2007-03-04', 'Doe' UNION ALL
SELECT 7, '2007-03-08', 'Jones' UNION ALL
SELECT 7, '2007-03-10', 'Jones' UNION ALL
SELECT 7, '2007-03-11', 'Jones' UNION ALL
SELECT 7, '2007-03-12', 'Doe' UNION ALL
SELECT 7, '2007-03-13', 'Doe' UNION ALL
SELECT 7, '2007-03-14', 'Doe' UNION ALL
SELECT 3, '2007-03-01', 'Jones' UNION ALL
SELECT 3, '2007-03-07', 'Doe' UNION ALL
SELECT 3, '2007-03-14', 'Jones'
-- Show the expected output
SELECT y.Patient,
COUNT(*) AS Occurancies
FROM (
SELECT x.Patient,
x.First_DT,
x.Second_DT,
MIN(a.Ser_DT) AS Third_DT
FROM (
SELECT a1.Patient,
a1.Ser_DT AS First_DT,
MIN(a2.Ser_DT) AS Second_DT
FROM @Appt AS a1
INNER JOIN @Appt AS a2 ON a2.Patient = a1.Patient AND a2.Ser_DT > a1.Ser_DT
GROUP BY a1.Patient,
a1.Ser_DT
) AS x
INNER JOIN @Appt AS a ON a.Patient = x.Patient AND a.Ser_DT > x.Second_DT
GROUP BY x.Patient,
x.First_DT,
x.Second_DT
) AS y
INNER JOIN @Appt AS z1 ON z1.Patient = y.Patient AND z1.Ser_DT = y.First_DT
INNER JOIN @Appt AS z2 ON z2.Patient = y.Patient AND z2.Ser_DT = y.Second_DT
INNER JOIN @Appt AS z3 ON z3.Patient = y.Patient AND z3.Ser_DT = y.Third_DT
WHERE z1.Prov = z2.Prov
AND z2.Prov = z3.Prov
GROUP BY y.Patient
ORDER BY y.Patient
N 56°04'39.16"
E 12°55'05.25"
April 12, 2007 at 11:17 pm
-- Prepare sample data
DECLARE @Appt TABLE (Patient INT, Ser_DT DATETIME, Prov VARCHAR(30))
INSERT @Appt
SELECT 1, '2007-03-01', 'Smith' UNION ALL
SELECT 1, '2007-03-02', 'Smith' UNION ALL
SELECT 1, '2007-03-03', 'Smith' UNION ALL
SELECT 1, '2007-03-04', 'Jones' UNION ALL
SELECT 7, '2007-03-01', 'Doe' UNION ALL
SELECT 7, '2007-03-04', 'Doe' UNION ALL
SELECT 7, '2007-03-08', 'Jones' UNION ALL
SELECT 7, '2007-03-10', 'Jones' UNION ALL
SELECT 7, '2007-03-11', 'Jones' UNION ALL
SELECT 7, '2007-03-12', 'Doe' UNION ALL
SELECT 7, '2007-03-13', 'Doe' UNION ALL
SELECT 7, '2007-03-14', 'Doe' UNION ALL
SELECT 3, '2007-03-01', 'Jones' UNION ALL
SELECT 3, '2007-03-07', 'Doe' UNION ALL
SELECT 3, '2007-03-14', 'Jones'
-- Stage the data
DECLARE @Stage TABLE (RecID INT IDENTITY(1, 1), Patient INT, Prov VARCHAR(30))
INSERT @Stage
SELECT y.Patient,
z1.Prov
FROM (
SELECT x.Patient,
x.First_DT,
x.Second_DT,
MIN(a.Ser_DT) AS Third_DT
FROM (
SELECT a1.Patient,
a1.Ser_DT AS First_DT,
MIN(a2.Ser_DT) AS Second_DT
FROM @Appt AS a1
INNER JOIN @Appt AS a2 ON a2.Patient = a1.Patient AND a2.Ser_DT > a1.Ser_DT
GROUP BY a1.Patient,
a1.Ser_DT
) AS x
INNER JOIN @Appt AS a ON a.Patient = x.Patient AND a.Ser_DT > x.Second_DT
GROUP BY x.Patient,
x.First_DT,
x.Second_DT
) AS y
INNER JOIN @Appt AS z1 ON z1.Patient = y.Patient AND z1.Ser_DT = y.First_DT
INNER JOIN @Appt AS z2 ON z2.Patient = y.Patient AND z2.Ser_DT = y.Second_DT
INNER JOIN @Appt AS z3 ON z3.Patient = y.Patient AND z3.Ser_DT = y.Third_DT
WHERE z1.Prov = z2.Prov
AND z2.Prov = z3.Prov
ORDER BY y.Patient
-- Show the expected output
SELECT s.Patient,
s.Prov
FROM @Stage AS s
INNER JOIN (
SELECT Patient,
MIN(RecID) AS RecID
FROM @Stage
GROUP BY Patient
) AS x ON x.RecID = s.RecID
N 56°04'39.16"
E 12°55'05.25"
April 13, 2007 at 12:41 pm
Thanks, Peter.
April 13, 2007 at 1:48 pm
Just another option
SELECT
A.PATIENT,
A.PROV
FROM
@Appt A
INNER JOIN
(
SELECT
PATIENT,
MIN(SER_DT) SER_DT
FROM
@Appt oX
WHERE
(SELECT COUNT(DISTINCT PROV) FROM (SELECT TOP 3 PROV, SER_DT FROM @appt iX WHERE iX.PATIENT = oX.PATIENT AND iX.SER_DT >= oX.SER_DT ORDER BY iX.PATIENT ASC, iX.SER_DT ASC) A GROUP BY PROV HAVING COUNT(SER_DT) = 3) = 1
GROUP BY
PATIENT
) B
ON
A.PATIENT = B.PATIENT AND
A.SER_DT = B.SER_DT
April 16, 2007 at 7:26 am
Hi ,
Try this one out.....
select * from @Appt a
join
(select patient,prov from @Appt
group by patient,prov
having count(*) =3) b
on a.patient=b.patient and
a.prov=b.prov
Thanks & Regards
Amit Gupta
April 16, 2007 at 9:04 am
Amit, add this test data to the existing one.
SELECT
7, '2007-03-09', 'Doe' UNION ALL
N 56°04'39.16"
E 12°55'05.25"
Viewing 7 posts - 1 through 6 (of 6 total)
You must be logged in to reply to this topic. Login to reply