简体   繁体   中英

Sql Server group by sets of columns

I have a data set where I need to count patient visits with such rules:

  1. Two or more visits to the same doctor in the same day count as 1 visit, regardless of the reason
  2. Two or more visits to different doctors for the same reason count as 1 visit
  3. Two or more visits to different doctors on the same day for different reasons count as two or more visits.

Example data:

DoctorId      PatientId       VisitDate       ReasonCode   RowId
--------      ---------       ---------       ----------   -----
1              100             2014-01-01        200         1 
1              100             2014-01-01        210         2
2              100             2014-01-01        200         3
2              100             2014-01-11        300         4
1              100             2014-01-15        200         5
2              400             2014-01-15        200         6

In this example, my final count would be based on grouping rowId 1, 2, 3 for 1 visit; grouping row 4 as 1 visit, grouping row 5 as 1 visit for a total of 3 visits for patient 100. Patient 400 has 1 visit as well.

patientid   visitdate   numberofvisits
---------   ---------   --------------
100         2014-01-01   3
100         2014-01-11   1
100         2014-01-15   1
400         2014-01-15   1

Where I'm stuck is how to handle the group by so that I get the different scenarios covered. If the grouping were doctor, date, I'd be fine. If it were doctor, date, ReasonCode, I'd be fine. It's the logic of the doctorId and the ReasonCode in the scenario where 2 doctors are involved, and doctorid and date in the other when it's the same doctor. I've not been deeply into Sql Server in a long time, so it's possible that a common table expression is the solution and I'm not seeing it. I'm using Sql Server 2014 and there's a decent lattitude in performance. I would be looking for a sql server query that produces the results above. As best I can tell, there's no way to group this the way I need it counted.

The answer was an except clause and grouping each of the sets before a final count. Sometimes, we over-complicate things.

DECLARE @tblAllData TABLE
(   
      DoctorId              INT NOT NULL
    , PatientId         INT NOT NULL
    , VisitDate         DATE NOT NULL
    , ReasonCode    INT NOT NULL
    , RowId                 INT NOT NULL
)

INSERT @tblAllData 
SELECT
        1,100,'2014-01-01',200,1
UNION ALL 
SELECT
    1,100,'2014-01-01',210,2
UNION ALL 
SELECT
2,100,'2014-01-01',200,3
UNION ALL 
SELECT
2,100,'2014-01-11',300,4
UNION ALL 
SELECT
1,100,'2014-01-15',200,5
UNION ALL 
SELECT
2,400,'2014-01-15',200,6

DECLARE @tblTempCountedRows AS TABLE
(
       PatientId                        INT NOT NULL    
    , VisitDate                     DATE
    , ReasonCode                INT 
)
INSERT @tblTempCountedRows

    SELECT PatientId, VisitDate,0 
         FROM @tblAllData       
    GROUP BY PatientId, DoctorId, VisitDate 
EXCEPT 
SELECT PatientId, VisitDate, ReasonCode
 FROM @tblAllData
 GROUP BY PatientId, VisitDate, ReasonCode

 select * from @tblTempCountedRows 

    DECLARE @tblFinalCountedRows AS TABLE
(
    PatientId                       INT NOT NULL    
 , VisitCount                   INT
)
 INSERT @tblFinalCountedRows 
SELECT 
    PatientId
, count(1) as Member_visit_Count
FROM
    @tblTempCountedRows 
GROUP BY PatientId

SELECT * from @tblFinalCountedRows

Here's a Sql Fiddle with the results: Sql Fiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM