如何构建SQL以按日期获取分组数据

时间:2018-10-23 09:31:45

标签: sql json postgresql

我在Postgres数据库中有这样的数据

 | id |  name  |    start_date       |      end_date       |
   1    Event1  2018-09-14 14:22:00     2018-09-15 14:22:00
   2    Event2  2018-09-15 14:22:00     2018-09-15 15:22:00

我需要SQL,该SQL返回我的响应group_by日期,并且如果事件持续时间(结束日期,开始日期)花费了2天,则我需要在两天的数组中两次返回他,所有这些都应该按日期排序。因此响应应该如下所示。

{
  "2018-09-14": [
      {
        "id": 1,
        "name": "Event1",
        "start_date": "2018-09-14 14:22:00",
        "end_date": "2018-09-15 14:22:00",
    }],
    "2018-09-15": [{
        "id": 1,
        "name": "Event1",
        "start_date": "2018-09-14 14:22:00",
        "end_date": "2018-09-15 14:22:00",
    },
    {
        "id": 2,
        "name": "Event2",
        "start_date": "2018-09-15 14:22:00",
        "end_date": "2018-09-15 15:22:00",
    }]
 }

您能帮我这个SQL吗?

2 个答案:

答案 0 :(得分:1)

demo: db<>fiddle

SELECT 
    jsonb_object_agg(dates, data_array)
FROM (
    SELECT
        dates,
        jsonb_agg(data) as data_array
    FROM (
        SELECT DISTINCT
            unnest(ARRAY[start_date::date, end_date::date]) as dates,
            row_to_json(events)::jsonb as data
        FROM
            events
    )s
    GROUP BY dates
) s
  1. 使用row_to_json将表转换为json对象。
  2. 使用ARRAY[]将两个日期汇总到一个数组中
  3. unnest()会在每个日期扩展数据。

到目前为止的结果:

dates        data
2018-09-14   {"id": 1, "name": "Event1", "end_date": "2018-09-15 14:22:00", "start_date": "2018-09-14 14:22:00"}
2018-09-15   {"id": 1, "name": "Event1", "end_date": "2018-09-15 14:22:00", "start_date": "2018-09-14 14:22:00"}
2018-09-15   {"id": 2, "name": "Event2", "end_date": "2018-09-15 15:22:00", "start_date": "2018-09-15 14:22:00"}
2018-09-15   {"id": 2, "name": "Event2", "end_date": "2018-09-15 15:22:00", "start_date": "2018-09-15 14:22:00"}
  1. DISTINCT消除了start_date == end_date中所有相关的元素。
  2. 按日期分组,将json元素聚合到json数组(jsonb_agg
  3. 毕竟,使用jsonb_object_aggkey == date将表分组为json元素(value == json array

答案 1 :(得分:1)

如果只需要行,则只需执行以下步骤:

  1. 使用ARRAY[]将两个日期汇总到一个数组中
  2. unnest()会在每个日期扩展数据。
  3. DISTINCT消除了start_date == end_date中所有相关的元素。

查询

SELECT DISTINCT
    unnest(ARRAY[start_date::date, end_date::date]) as dates,
    *
FROM
    events

结果

dates        id   name     start_date            end_date
2018-09-14   1    Event1   2018-09-14 14:22:00   2018-09-15 14:22:00
2018-09-15   1    Event1   2018-09-14 14:22:00   2018-09-15 14:22:00
2018-09-15   2    Event2   2018-09-15 14:22:00   2018-09-15 15:22:00

demo:db<>fiddle