1

我有 3 张桌子:

doctors (id, name) -> has_many:
    patients (id, doctor_id, name) -> has_many:
        health_conditions (id, patient_id, note, created_at)

每天每位患者都会添加一个健康状况,并附有从 1 到 10 的注释,其中 10 表示身体健康(如果可以的话,可以完全康复)。

我要提取的是过去 30 天(月)的以下 3 个统计数据: - 有多少患者好转 - 有多少患者病情恶化 - 有多少患者保持不变

这些统计数据是全球性的,所以我现在不关心每个医生的统计数据,我可以根据正确的查询提取这些数据。

诀窍是查询需要提取当前的 health_condition 注释并与过去几天的平均值(本月没有今天)进行比较,因此需要提取今天的注释和除此之外的其他日期的平均值。

我认为查询不需要定义谁上/下/相同,因为我可以循环并决定。我想,就在今天和本月的其余时间就足够了。

这是我到目前为止所拥有的 obv。不起作用,因为由于应用了限制,它只返回一个结果:

SELECT
    p.id,
    p.name,
    hc.latest,
    hcc.average
FROM
    pacients p
INNER JOIN (
        SELECT
            id,
            pacient_id,
            note as LATEST
        FROM
            health_conditions
        GROUP BY pacient_id, id
        ORDER BY created_at DESC
        LIMIT 1
    ) hc ON(hc.pacient_id=p.id)
INNER JOIN (
        SELECT
            id,
            pacient_id,
            avg(note) AS average
        FROM
            health_conditions
        GROUP BY pacient_id, id
    ) hcc ON(hcc.pacient_id=p.id AND hcc.id!=hc.id)
WHERE
    date_part('epoch',date_trunc('day', hcc.created_at))
    BETWEEN
        (date_part('epoch',date_trunc('day', hc.created_at)) - (30 * 86400))
    AND
        date_part('epoch',date_trunc('day', hc.created_at))

该查询具有区分最新和平均所需的所有逻辑,但该限制会扼杀一切。我需要该限制来提取用于与过去结果进行比较的最新结果。

4

2 回答 2

1
SELECT SUM(delta < 0) AS worsened,
       SUM(delta = 0) AS no_change,
       SUM(delta > 0) AS improved
FROM  (
  SELECT   patient_id,
           SUM(IF(DATE(created_at) = CURDATE(),note,NULL))
         - AVG(IF(DATE(created_at) < CURDATE(),note,NULL)) AS delta
  FROM     health_conditions
  WHERE    DATE(created_at) BETWEEN CURDATE() - INTERVAL 1 MONTH AND CURDATE()
  GROUP BY patient_id
) t
于 2012-08-24T16:23:52.307 回答
1

像这样的假设created_at是类型date

select p.name,
       hc.note as current_note,
       av.avg_note
from patients p
   join health_conditions hc on hc.patient_id = p.id
   join (
      select patient_id, 
             avg(note) as avg_note
      from health_conditions hc2
      where created_at between current_date - 30 and current_date - 1
      group by patient_id
    ) avg on t.patient_id = hc.patient_id
where hc.created_at = current_date;

这是 PostgreSQL 语法。我不确定 MySQL 是否以同样的方式支持日期算术。

编辑:

这应该为您提供每位患者的最新记录,以及过去 30 天的平均值:

select p.name,
       hc.created_at as last_note_date
       hc.note as current_note,
       t.avg_note
from patients p
   join health_conditions hc 
     on hc.patient_id = p.id
    and hc.created_at = (select max(created_at) 
                         from health_conditions hc2 
                         where hc2.patient_id = hc.patient_id)
   join (
      select patient_id, 
             avg(note) as avg_note
      from health_conditions hc3
      where created_at between current_date - 30 and current_date - 1
      group by patient_id
    ) t on t.patient_id = hc.patient_id
于 2012-08-24T16:22:15.200 回答