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メモを抽出し、過去の日数の平均(今日なしの今月)と比較する必要があるため、今日のメモとこれを除く他の日の平均を抽出する必要があることです。

ループして決定できるので、クエリで誰が上がった/下がった/同じかを定義する必要はないと思います。今日とその月の残りの部分で十分だと思います。

これが私がこれまでに持っているものです。適用された制限のために1つの結果しか返さないため、機能しません。

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

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 に答える
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 に答える