根据上次就诊日期与医生对患者记录进行分组和统计

时间:2012-09-14 18:01:44

标签: sql sql-server sql-server-2008 tsql

这是我的数据:

+----------+---------------+------------+---------------------+
|  doctor  | received_date | patient_id | accession_daily_key |
+----------+---------------+------------+---------------------+
|  A       |  1/1/2011     |  ABC123    |                   1 |
|  A       |  1/20/2011    |  AAA123    |                   2 |
|  A       |  1/21/2011    |  AAA123    |                   3 |
|          |               |            |                   4 |
|  A       |  2/1/2011     |  ABC123    |                   5 |
|  A       |  2/9/2011     |  BBBYYY    |                   6 |
|          |               |            |                   7 |
|  B       |  1/2/2011     |  ABC123    |                   8 |
|  B       |  1/20/2011    |  AXA435    |                   9 |
|  B       |  1/19/2011    |  AAA123    |                  10 |
|          |               |            |                  11 |
|  B       |  2/1/2011     |  ABC123    |                  12 |
|  B       |  2/10/2011    |  BBBYYY    |                  13 |
+----------+---------------+------------+---------------------+

这是我想要的结果:

+--------+-------+--------------------+
| doctor | month | count new patients |
+--------+-------+--------------------+
| A      |     1 |                  1 |
| A      |     2 |                  1 |
| B      |     1 |                  2 |
| B      |     2 |                  0 |
+--------+-------+--------------------+

我想每月为新医生计算一名医生。

我获得的业务规则是:

  
      
  1. 患者只能与一名医生联系
  2.   
  3. 患者所关联的医生是看见他的最后一位医生
  4.   

这是我到目前为止所拥有的:

select patient_id,max(month(RECEIVED_DATE)) AS Mnth, max(year(RECEIVED_DATE)) AS Yr, ACCESSION_DAILY_KEY
    FROM [F_ACCESSION_DAILY] 
    where RECEIVED_MLIS_INFORMATION=1
    GROUP BY patient_id,ACCESSION_DAILY_KEY

此查询将为我提供包含患者所关联医生的行的primary key accession_daily_key

您能否指导我如何在每个月为每位医生提供每月最新的患者数量?


jcolebrand编辑:

CREATE TABLE F_ACCESSION_DAILY (
    doctor VARCHAR(10) NOT NULL
  , received_date DATETIME NOT NULL
  , patient_id VARCHAR(10) NOT NULL
  , accession_daily_key INT NOT NULL
)

INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('A','1/1/2011','ABC123','1')
INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('A','1/20/2011','AAA123','2')
INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('A','1/21/2011','AAA123','3')
INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('A','2/1/2011','ABC123','5')
INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('A','2/9/2011','BBBYYY','6')
INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('B','1/2/2011','ABC123','8')
INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('B','1/20/2011','AXA435','9')
INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('B','1/19/2011','AAA123','10')
INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('B','2/1/2011','ABC123','12')
INSERT INTO F_ACCESSION_DAILY (doctor,received_date,patient_id,accession_daily_key) VALUES ('B','2/10/2011','BBBYYY','13')

2 个答案:

答案 0 :(得分:4)

您可能需要使用子查询分两步执行此操作:

  1. 获取所有新患者就诊的清单:

    选择医生,MIN(日期)AS首次访问,患者FROM访问GROUP BY患者;

  2. 按月分组

    SELECT医生,COUNT(*),MONTH(firstvisit)AS月,YEAR(firstvisit)AS年份(...)GROUP BY医生,MONTH(firstvisit),YEAR(firstvisit);

  3. 总而言之,以下内容应该有效:

    SELECT doctor, COUNT(*) newPatients, MONTH(firstvisit) AS month, YEAR(firstvisit) AS year FROM 
            (SELECT doctor, MIN(date) AS firstvisit ,patient FROM visits GROUP BY patient)
        GROUP BY doctor, MONTH(firstvisit), YEAR(firstvisit);
    

    没有子查询可能会这样做,但我不确定它是否能正常工作。

    好的,编辑更新:

    您现在需要四个(?)步骤:

    1. 确定每位患者的最后一次就诊

      SELECT患者,MAX(日期)lastvisit FROM访问GROUP BY患者;

    2. 确定每位专利的相关医生,作为上次就诊的医生:

      选择医生,患者FROM访问v LEFT JOIN(...)lv ON v.patient = lv.patient WHERE v.date = lv.lastvisit;

    3. 与他们的最新医生确定第一次就诊

      选择医生,患者,MIN(日期)firstvisit     来自访问v     LEFT JOIN(...)dp ON v.doctor = dp.doctor     WHERE v.patient = dp.patient     GROUP BY患者;

    4. 和以前一样,每个医生每月第一次就诊:

      SELECT医生,COUNT(*),MONTH(firstvisit)AS月,YEAR(firstvisit)AS年     FROM(...)GROUP by doctor,MONTH(firstvisit),YEAR(firstvisit);

    5. 给予一个稍微可怕且有效的总数:

      SELECT doctor, COUNT(*), MONTH(firstvisit) AS month, YEAR(firstvisit) AS year 
          FROM (
          SELECT doctor, patient, MIN(date) firstvisit
              FROM visits v 
              LEFT JOIN (
                  SELECT doctor, patient FROM visits v 
                      LEFT JOIN (
                          SELECT patient, date lastvisit 
                              FROM visits GROUP BY patient) lv 
                      ON v.patient=lv.patient 
                      WHERE v.date=lv.lastvisit) dp 
              ON v.doctor=dp.doctor
              WHERE v.patient=dp.patient
              GROUP BY patient) 
          GROUP BY doctor, MONTH(firstvisit), YEAR(firstvisit);
      

      我认为这可能至少会被压缩一点。

      EDIT2:感谢jcolebrand,正在使用SQL:http://sqlfiddle.com/#!3/41beb/25

      SELECT
             t.doctor
           , COUNT(t.doctor)
           , MONTH(t.firstvisit) AS MONTH
           , YEAR(t.firstvisit) AS YEAR
        FROM (
          SELECT
                 v.doctor
               , v.patient_id
               , MIN(received_date) firstvisit
            FROM F_ACCESSION_DAILY v
       LEFT JOIN (
                  SELECT
                         v.doctor
                       , v.patient_id
                    FROM F_ACCESSION_DAILY v
               LEFT JOIN (
                          SELECT patient_id
                               , received_date lastvisit
                            FROM F_ACCESSION_DAILY
                        GROUP BY patient_id
                               , received_date
                        ) lv ON v.patient_id=lv.patient_id
                   WHERE v.received_date=lv.lastvisit
                ) dp ON v.doctor = dp.doctor
          WHERE v.patient_id=dp.patient_id
          GROUP BY v.patient_id
                 , v.doctor
        ) t
       GROUP BY
             t.doctor
           , MONTH(t.firstvisit)
           , YEAR(t.firstvisit);
      

答案 1 :(得分:4)

  

请注意,这是他的第一次信息迭代,并且因为Zeb已经做了一个很好的工作并得到了进一步的答案,我将其留下来用于历史追踪。你可以随意忽略这个答案,但是对于迭代过程,这是一个很好的学习范例。

这似乎应该做你需要的,我想

SELECT
       MIN(received_date) AS FirstVisit
     , patient_id         AS PatientID
INTO #LookupTable
FROM F_ACCESSION_DAILY

SELECT 
       f.doctor           AS Doctor
     , COUNT(f.*)         AS CountNewPatients
     , MONTH(firstvisit)  AS Month
     , YEAR(firstvisit)   AS Year
FROM F_ACCESSION_DAILY f 
INNER JOIN #LookupTable l ON f.received_date = l.FirstVisit 
                         AND f.patient_id = l.PatientID
GROUP BY f.doctor
       , MONTH(firstvisit)
       , YEAR(firstvisit)

DROP TABLE #LookupTable