【问题标题】:How to get Postgres records in higher date resolution (4 hours, 1 day, 1 week, 1 month - hourly, daily. monthly) from 1 hour timestamp table如何从 1 小时时间戳表中以更高的日期分辨率(4 小时、1 天、1 周、1 个月 - 每小时、每天。每月)获取 Postgres 记录
【发布时间】:2021-05-08 21:36:41
【问题描述】:

给定下表,该表以 1 小时为间隔:

| id  | created_at                    | tt | vv  |
| --- | ----------------------------- | -- | --- |
| 1   | 2021-05-08 16:00:01.384687+00 | A  | 100 |
| 2   | 2021-05-08 16:00:03.435737+00 | B  | 50  |
| 3   | 2021-05-08 17:01:00.388957+00 | A  | 101 |
| 4   | 2021-05-08 17:02:00.43814+00  | B  | 49  |
| 5   | 2021-05-08 18:00:30.685336+00 | A  | 102 |
| 6   | 2021-05-08 18:00:40.731571+00 | B  | 48  |
| 7   | 2021-05-08 19:01:02.566949+00 | A  | 103 |
| 8   | 2021-05-08 19:02:00.576785+00 | B  | 47  |
| 9   | 2021-05-08 20:03:10.566949+00 | A  | 104 |
| 10  | 2021-05-08 20:05:00.576785+00 | B  | 46  |

地点:

  • id 是主键
  • created_at 是带有 tz 的 时间戳
  • tt 是一个字符串/文本;和
  • vv 是一个数字

我正在寻找 Postgres 查询字符串 以获取分段为 2 小时/4 小时/24 小时/1 周/的数据(created_at、tt、vv) 1 个月间隔。因此,2 小时间隔的示例结果表将是:

| id  | created_at                    | tt   | vv  |
| --- | ----------------------------- | ---- | --- |
| 1   | 2021-05-08 16:00:00.000000+00 | A    | 100 |
| 2   | 2021-05-08 16:00:00.000000+00 | B    | 50  |
| 5   | 2021-05-08 18:00:00.000000+00 | A    | 102 |
| 6   | 2021-05-08 18:00:00.000000+00 | B    | 48  |
| 9   | 2021-05-08 20:00:00.000000+00 | A    | 104 |
| 10  | 2021-05-08 20:00:00.000000+00 | B    | 46  |

我尝试使用here 中描述的间隔时间线并将其与 WITH 语句结合使用,但未成功。 注意:我不是在寻找求和列,而是在寻找上表中所述的聚合。

因此,输出应该具有与使用时相同的结构

SELECT date_trunc('second', created_at) as time, tt, vv FROM tbl GROUP BY created_at, tt, vv order by time desc

如果可以灵活地以 ms 或 s 指定间隔,则奖励。谢谢!

【问题讨论】:

    标签: postgresql date


    【解决方案1】:

    您需要按年、月、日和小时分组,请参见下面的示例

    CREATE TABLE table1 (
      "id" INTEGER,
      "created_at" timestamp,
      "tt" VARCHAR(1),
      "vv" INTEGER
    );
    
    INSERT INTO table1
      ("id", "created_at", "tt", "vv")
    VALUES
      ('1', '2021-05-08 16:00:01.384687+00', 'A', '100'),
      ('2', '2021-05-08 16:00:03.435737+00', 'B', '50'),
      ('3', '2021-05-08 17:01:00.388957+00', 'A', '101'),
      ('4', '2021-05-08 17:02:00.43814+00', 'B', '49'),
      ('5', '2021-05-08 18:00:30.685336+00', 'A', '102'),
      ('6', '2021-05-08 18:00:40.731571+00', 'B', '48'),
      ('7', '2021-05-08 19:01:02.566949+00', 'A', '103'),
      ('8', '2021-05-08 19:02:00.576785+00', 'B', '47'),
      ('9', '2021-05-08 20:03:10.566949+00', 'A', '104'),
      ('10', '2021-05-08 20:05:00.576785+00', 'B', '46');
    
    WITH CTE AS (
    SELECT 
    "id", "created_at", "tt", "vv",
      ROW_NUMBER () OVER (
          PARTITION BY "tt"
    ,EXTRACT(year from  "created_at")
    ,EXTRACT(Month from  "created_at")
    ,EXTRACT(day from  "created_at")
    ,trunc(EXTRACT(hour from  "created_at") / 2)
          ORDER BY
              "created_at"
      ) as rown
      FROM table1)
    SELECT "id", date_trunc('hour',"created_at"), "tt", "vv"
    FROM CTE 
    WHERE CTE.rown = 1
    ORDER BY "id"
    
    编号 |日期截断 | tt | vv -: | :----------------- | :- | --: 1 | 2021-05-08 16:00:00 |一个 | 100 2 | 2021-05-08 16:00:00 |乙| 50 5 | 2021-05-08 18:00:00 |一个 | 102 6 | 2021-05-08 18:00:00 |乙| 48 9 | 2021-05-08 20:00:00 |一个 | 104 10 | 2021-05-08 20:00:00 |乙| 46
    SELECT 
    "id", "created_at", "tt", "vv",
      ROW_NUMBER () OVER (
          PARTITION BY "tt"
    ,EXTRACT(year from  "created_at")
    ,EXTRACT(Month from  "created_at")
    ,EXTRACT(day from  "created_at")
    ,trunc(EXTRACT(hour from  "created_at") / 2)
          ORDER BY
              "created_at"
      ) as rown
      FROM table1
    
    编号 | created_at | tt | vv |罗恩 -: | :------------------------- | :- | --: | ---: 1 | 2021-05-08 16:00:01.384687 |一个 | 100 | 1 3 | 2021-05-08 17:01:00.388957 |一个 | 101 | 2 5 | 2021-05-08 18:00:30.685336 |一个 | 102 | 1 7 | 2021-05-08 19:01:02.566949 |一个 | 103 | 2 9 | 2021-05-08 20:03:10.566949 |一个 | 104 | 1 2 | 2021-05-08 16:00:03.435737 |乙| 50 | 1 4 | 2021-05-08 17:02:00.43814 |乙| 49 | 2 6 | 2021-05-08 18:00:40.731571 |乙| 48 | 1 8 | 2021-05-08 19:02:00.576785 |乙| 47 | 2 10 | 2021-05-08 20:05:00.576785 |乙| 46 | 1
    SELECT 
    MIN("id"), MIN("created_at"), "tt", SUM("vv")
    
    FROM table1 
    group by "tt"
    ,EXTRACT(year from  "created_at")
    ,EXTRACT(Month from  "created_at")
    ,EXTRACT(day from  "created_at")
    ,trunc(EXTRACT(hour from  "created_at") / 2) 
    
    分钟 |分钟 | tt |和 --: | :------------------------- | :- | --: 5 | 2021-05-08 18:00:30.685336 |一个 | 205 1 | 2021-05-08 16:00:01.384687 |一个 | 201 10 | 2021-05-08 20:05:00.576785 |乙| 46 6 | 2021-05-08 18:00:40.731571 |乙| 95 2 | 2021-05-08 16:00:03.435737 |乙| 99 9 | 2021-05-08 20:03:10.566949 |一个 | 104
    SELECT 
    MIN("id"), MIN("created_at"), "tt", SUM("vv")
    
    FROM table1 
    group by "tt"
    ,EXTRACT(year from  "created_at")
    ,EXTRACT(Month from  "created_at")
    ,EXTRACT(day from  "created_at")
    ,trunc(EXTRACT(hour from  "created_at") / 4) 
    
    分钟 |分钟 | tt |和 --: | :------------------------- | :- | --: 1 | 2021-05-08 16:00:01.384687 |一个 | 406 9 | 2021-05-08 20:03:10.566949 |一个 | 104 10 | 2021-05-08 20:05:00.576785 |乙| 46 2 | 2021-05-08 16:00:03.435737 |乙| 194
    ;SELECT 
    MIN("id"), MIN("created_at"), "tt", SUM("vv")
    
    FROM table1 
    group by "tt"
    ,EXTRACT(year from  "created_at")
    ,EXTRACT(Month from  "created_at")
    ,EXTRACT(day from  "created_at")
    
    分钟 |分钟 | tt |和 --: | :------------------------- | :- | --: 1 | 2021-05-08 16:00:01.384687 |一个 | 510 2 | 2021-05-08 16:00:03.435737 |乙| 240
    ;SELECT 
    MIN("id"), MIN("created_at"), "tt", SUM("vv")
    
    FROM table1 
    group by "tt"
    ,EXTRACT(year from  "created_at")
    ,EXTRACT(Month from  "created_at")
    ,EXTRACT(week from "created_at") 
    
    分钟 |分钟 | tt |和 --: | :------------------------- | :- | --: 1 | 2021-05-08 16:00:01.384687 |一个 | 510 2 | 2021-05-08 16:00:03.435737 |乙| 240
    ;SELECT 
    MIN("id"), MIN("created_at"), "tt", SUM("vv")
    
    FROM table1 
    group by "tt"
    ,EXTRACT(year from  "created_at")
    ,EXTRACT(Month from  "created_at")
    
    分钟 |分钟 | tt |和 --: | :---------------------------- | :- | --: 2 | 2021-05-08 16:00:03.435737 |乙| 240 1 | 2021-05-08 16:00:01.384687 |一个 | 510

    db小提琴here

    【讨论】:

    • 太好了,如果我不想要总和而是“vv”怎么办?
    • Select 中的所有列必须在 GROUP By 中或有聚合函数,sum 和 MIN 仅用于演示目的,否则会报错。 , 但这不是你的问题,如果你想知道其他事情,那么约会问一个新的并接受答案
    • 我给出了一个查询结果示例(包括 vv,不包括 sum)和示例结果表(包括 vv,不包括 sum)。
    • 我愿意接受答案并感谢您的努力,但如果没有 vv 列,它就没有用处。
    • 我接受了这个答案,因为它结合了“SELECT * from x”查询提供了分段。我仍然会寻找一种在 ONE 查询中输出上述所需结果的解决方案。感谢您的努力!
    猜你喜欢
    • 1970-01-01
    • 2019-05-29
    • 1970-01-01
    • 2015-05-26
    • 1970-01-01
    • 2016-02-27
    • 1970-01-01
    • 2017-04-26
    • 1970-01-01
    相关资源
    最近更新 更多