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