简体   繁体   English

PostgreSQL 中的嵌套行分组

[英]Nested grouping of rows in PostgreSQL

I have the following "Transactions" table in PostgreSQL 11:我在 PostgreSQL 11 中有以下“交易”表:

    |=====================|==================|==================|===========================|
    |        owner        |      amount      |     category     |        timestamp          |
    |=====================|==================|==================|===========================|
    |        robb         |        34        |       food       |  2020-01-30 18:30:00+00   |
    |---------------------|------------------|------------------|---------------------------|
    |        ned          |       1500       |      travel      |  2020-03-15 15:00:00+00   |
    |---------------------|------------------|------------------|---------------------------|
    |        jon          |        56        |     equipment    |  2020-01-01 11:30:00+00   |
    |---------------------|------------------|------------------|---------------------------|
    |        petyr        |        78        |       food       |  2020-06-29 14:30:00+00   |
    |---------------------|------------------|------------------|---------------------------|

My final goal is to get an object in my webservice (NodeJS) of the following schema:我的最终目标是在我的 web 服务 (NodeJS) 中获得以下模式的 object:

{
  "food": {
    "2020-01-01": [...], // Array of Rows (JSON) that have category = "food" and timestamp within Jan-20
    "2020-06-01": [...] // Array of Rows (JSON) that have category = "food" and timestamp within Jun-20
  },
  "travel": {
    "2020-03-01": [...] // Array of Rows (JSON) that have category = "travel" and timestamp within Mar-20
  },
  "equipment": {
    "2020-01-01": [...] // Array of Rows (JSON) that have category = "equipment" and timestamp within Jan-20
  }
}

I am no expert in SQL, but I reckon it will require the following two steps:我不是 SQL 的专家,但我估计它需要以下两个步骤:

  1. Group the rows in the table by category.按类别对表格中的行进行分组。
  2. Now, take each group formed in point 1, and group the rows inside it by time interval truncated to month.现在,对第 1 点中形成的每个组进行分组,并按截断为月份的时间间隔对其中的行进行分组。

I am aware of only the basics of SQL and PostgreSQL. I was able to group the rows individually by category and interval using the following two queries:我只知道 SQL 和 PostgreSQL 的基础知识。我能够使用以下两个查询按类别和间隔对行进行单独分组:

  1. Grouping by category:按类别分组:

    SELECT category, JSON_AGG(ROW_TO_JSON("Transactions")) as results FROM "Transactions" GROUP BY category;

  2. Grouping by time interval:按时间间隔分组:

    SELECT date_trunc('month', timestamp) as interval, JSON_AGG(ROW_TO_JSON("Transactions")) as results FROM "Transactions" GROUP BY interval;

But how to combine these two queries and produce a result like the JSON object I've mentioned above?但是如何组合这两个查询并产生像我上面提到的 JSON object 这样的结果呢?

Use two levels of aggregation.使用两个级别的聚合。 I think you want:我想你想要:

SELECT category,
       JSON_AGG(JSON_BUILD_OBJECT(interval, results))
FROM (SELECT category,
             date_trunc('month', timestamp) as interval,
             JSON_AGG(ROW_TO_JSON("Transactions")) as results
      FROM "Transactions"
      GROUP BY category, interval
     ) i
GROUP BY category;

SELECT category,JSON_AGG(JSON_BUILD_OBJECT(interval, results)) FROM (SELECT category,date_trunc('month', timestamp) as interval,JSON_AGG(ROW_TO_JSON(txn)) as results FROM txn GROUP BY category,timestamp having (category='food' AND timestamp<'2020-02-01') OR (category='food' AND timestamp<'2020-07-01') OR (category='travel' AND timestamp<'2020-04-01') OR (category='equipment' AND timestamp<'2020-02-01')) i GROUP BY category; SELECT 类别,JSON_AGG(JSON_BUILD_OBJECT(间隔,结果))来自(SELECT 类别,date_trunc('月',时间戳)作为间隔,JSON_AGG(ROW_TO_JSON(txn))作为来自 txn GROUP BY 类别的结果,时间戳具有(类别='食物' AND timestamp<'2020-02-01') OR (category='food' AND timestamp<'2020-07-01') OR (category='travel' AND timestamp<'2020-04-01') OR ( category='equipment' AND timestamp<'2020-02-01')) i GROUP BY category;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM