SQL选择日期范围内的平均分数

时间:2012-08-24 16:10:50

标签: mysql sql postgresql

我有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注释并与过去几天的平均值(今天没有今天)进行比较,因此需要提取今天的注释以及除此之外的其他日期的平均值。

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

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

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))

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

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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
相关问题