Sql 按日期聚合多个记录

Sql 按日期聚合多个记录,sql,oracle,Sql,Oracle,我有一个模型,看起来像: MedicationAdherence { :id => :integer, :adherence_date => :date, :scheduled_time => :string, :acknowledged_at => :datetime, :patient_id => :integer, :created_at => :datet

我有一个模型,看起来像:

MedicationAdherence {
                 :id => :integer,
     :adherence_date => :date,
     :scheduled_time => :string,
    :acknowledged_at => :datetime,
         :patient_id => :integer,
         :created_at => :datetime,
         :updated_at => :datetime
}
我有7个记录(相同的
患者id
):

我期望的结果是将上述记录分组为以下输出:

{
    "adherence_date" => 2017-10-1,
           "morning" => 1,
         "afternoon" => 0,
           "evening" => nil,
             "night" => 1
},
{
    "adherence_date" => 2017-10-2,
           "morning" => 1,
         "afternoon" => 1,
           "evening" => 1,
             "night" => 0
}
如果没有记录(2017年10月1日晚),则应返回零。当有记录但未确认时,应返回
false
(0),当有确认时,应返回
true
(1)

下面是我用来尝试合并所有这些数据的查询,但它给了我重复的记录。我如何将我的数据汇总到上面的数据中……我相信有一种更简单的方法可以做到这一点

WITH
  adherences AS (
    SELECT * FROM medication_adherences WHERE patient_id = 10049
  ),

  morning AS (
    SELECT adherence_date,
      CASE acknowledged_at WHEN null THEN 0 ELSE 1 END as morning
    FROM adherences
    WHERE scheduled_time = 'morning'
  ),

  afternoon as (
    SELECT adherence_date,
      CASE acknowledged_at WHEN null THEN 0 ELSE 1 END as afternoon
    FROM adherences
    WHERE scheduled_time = 'afternoon'
  ),

  evening as (
    SELECT adherence_date,
      CASE acknowledged_at WHEN null THEN 0 ELSE 1 END as evening
    FROM adherences
    WHERE scheduled_time = 'evening'
  ),

  night as (
    SELECT adherence_date,
      CASE acknowledged_at WHEN null THEN 0 ELSE 1 END as night
    FROM adherences
    WHERE scheduled_time = 'night'
  )

SELECT morning.morning, afternoon.afternoon, evening.evening, night.night, adherences.adherence_date
FROM adherences
LEFT JOIN morning ON morning.adherence_date = adherences.adherence_date
LEFT JOIN afternoon ON afternoon.adherence_date = adherences.adherence_date
LEFT JOIN evening ON evening.adherence_date = adherences.adherence_date
LEFT JOIN night ON night.adherence_date = adherences.adherence_date
我正在运行oracle-12c

编辑


看来我必须在我的查询中添加
按早晨、上午、下午、下午、晚上、晚上、晚上、晚上、坚持时间
分组,以便正确分组。有没有更简单的方法来聚合这些数据?

我不是Oracle开发人员,但您缺少的是group by子句。。。如果要计算记录数,可以将MAX替换为SUM

Select MAX(Morning.Morning), MAX(afternoon.afternoon), MAX(evening.evening), MAX(night.night), adherences.adherence_date
FROM medication_adherences 
LEFT JOIN morning ON morning.adherence_date = adherences.adherence_date
LEFT JOIN afternoon ON afternoon.adherence_date = adherences.adherence_date
LEFT JOIN evening ON evening.adherence_date = adherences.adherence_date
LEFT JOIN night ON night.adherence_date = adherences.adherence_date
WHERE patient_id = 10049
GROUP BY adherences.adherence_date

我会摆脱CTE的附庸,因为我们真的不需要它。。。您仍然需要在这个查询上添加上午、下午等CTE。

我不是Oracle开发人员,但您缺少的是group by子句。。。如果要计算记录数,可以将MAX替换为SUM

Select MAX(Morning.Morning), MAX(afternoon.afternoon), MAX(evening.evening), MAX(night.night), adherences.adherence_date
FROM medication_adherences 
LEFT JOIN morning ON morning.adherence_date = adherences.adherence_date
LEFT JOIN afternoon ON afternoon.adherence_date = adherences.adherence_date
LEFT JOIN evening ON evening.adherence_date = adherences.adherence_date
LEFT JOIN night ON night.adherence_date = adherences.adherence_date
WHERE patient_id = 10049
GROUP BY adherences.adherence_date
我会摆脱CTE的附庸,因为我们真的不需要它。。。您仍然需要在该查询的顶部设置上午、下午等CTE。

我假设
(患者id、坚持日期、计划时间)
在您的表格中是唯一的,这意味着患者可以在每个“时段”和日期预订一次

with medication_adherences  as(
-- This is your test data
   select 10049 as patient_id, 1 as id, date '2017-10-01' as adherence_date, 'morning'    as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 2 as id, date '2017-10-01' as adherence_date, 'afternoon'  as scheduled_time, null                            as acknowledged_at from dual union all                          
   select 10049 as patient_id, 3 as id, date '2017-10-01' as adherence_date, 'night'      as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 4 as id, date '2017-10-02' as adherence_date, 'morning'    as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 5 as id, date '2017-10-02' as adherence_date, 'afternoon'  as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 6 as id, date '2017-10-02' as adherence_date, 'evening'    as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 7 as id, date '2017-10-02' as adherence_date, 'night'      as scheduled_time, null                            as acknowledged_at from dual
)
select adherence_date
      ,sum(case when scheduled_time = 'morning'   then nvl2(acknowledged_at,1,0) end) as morning
      ,sum(case when scheduled_time = 'afternoon' then nvl2(acknowledged_at,1,0) end) as afternoon
      ,sum(case when scheduled_time = 'evening'   then nvl2(acknowledged_at,1,0) end) as evening
      ,sum(case when scheduled_time = 'night'     then nvl2(acknowledged_at,1,0) end) as night
  from medication_adherences 
 where patient_id = 10049
 group
    by adherence_date;
逻辑如下:

  • 如果确认的_at为空,则我们聚合0(通过nvl2)
  • 如果确认的_at为空,则我们聚合1(通过nvl2)
  • 如果此时间段没有记录,则聚合null(从…失败时起)
我假设
(患者id、坚持日期、计划时间)
在您的表格中是唯一的,这意味着患者可以在每个“时段”和日期预订一次

with medication_adherences  as(
-- This is your test data
   select 10049 as patient_id, 1 as id, date '2017-10-01' as adherence_date, 'morning'    as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 2 as id, date '2017-10-01' as adherence_date, 'afternoon'  as scheduled_time, null                            as acknowledged_at from dual union all                          
   select 10049 as patient_id, 3 as id, date '2017-10-01' as adherence_date, 'night'      as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 4 as id, date '2017-10-02' as adherence_date, 'morning'    as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 5 as id, date '2017-10-02' as adherence_date, 'afternoon'  as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 6 as id, date '2017-10-02' as adherence_date, 'evening'    as scheduled_time, timestamp '2017-10-31 19:59:19' as acknowledged_at from dual union all
   select 10049 as patient_id, 7 as id, date '2017-10-02' as adherence_date, 'night'      as scheduled_time, null                            as acknowledged_at from dual
)
select adherence_date
      ,sum(case when scheduled_time = 'morning'   then nvl2(acknowledged_at,1,0) end) as morning
      ,sum(case when scheduled_time = 'afternoon' then nvl2(acknowledged_at,1,0) end) as afternoon
      ,sum(case when scheduled_time = 'evening'   then nvl2(acknowledged_at,1,0) end) as evening
      ,sum(case when scheduled_time = 'night'     then nvl2(acknowledged_at,1,0) end) as night
  from medication_adherences 
 where patient_id = 10049
 group
    by adherence_date;
逻辑如下:

  • 如果确认的_at为空,则我们聚合0(通过nvl2)
  • 如果确认的_at为空,则我们聚合1(通过nvl2)
  • 如果此时间段没有记录,则聚合null(从…失败时起)

我尝试添加分组依据,但出现错误:
OCIRROR:ORA-00979:不是分组依据表达式
如果您尝试我上面提供的查询,则我遗漏了坚持。坚持日期。。。更新。正如我所提到的,我不使用Oracle RDBMS,因此无法检查syntaxI尝试添加GROUP BY的情况,但我得到了错误:
OCIRROR:ORA-00979:不是GROUP BY表达式
如果您尝试我上面提供的查询,我就错过了坚持性。坚持性\u日期。。。更新。正如我提到的,我不使用Oracle RDBMS,因此无法检查语法当我通过ORM(ActiveRecord/Rails)查看此视图时,它将早晚字段解释为整数,而不是布尔值。这是因为
sum
函数吗?它们实际上是整数,而不是布尔值:)当我通过ORM(ActiveRecord/Rails)查看此视图时,它将上午、下午、晚上和晚上的字段解释为整数,而不是布尔值。这是因为
sum
函数吗?它们实际上是整数而不是布尔值:)