【问题标题】:Using COUNT with aggregate in Postgres在 Postgres 中使用 COUNT 和聚合
【发布时间】:2021-07-18 18:55:17
【问题描述】:

我正在运行以下查询来检索我的数据:

SELECT
    e.id AS id, e.name AS name, e.description AS description,
    c.slug AS category,
    COUNT(t.id) AS sold,
    json_agg(json_build_object('id', b.id, 'title', b.title, 'description', b.description,'price', b.price, 'available', b.qty_available, 'qty_per_sale', b.qty_per_sale))::JSONB AS book,
    json_agg(json_build_object('id', s.id, 'startDate', s.start_date, 'endDate', s.end_date,'daysAhead', (s.start_date::DATE - NOW()::DATE), 'times', s.times))::JSONB as dates
FROM event e
    LEFT JOIN books b ON b.event_id = e.id
    LEFT JOIN shows s ON s.event_id = e.id
    LEFT JOIN category c ON e.category_id = c.id
    LEFT JOIN ticket t ON t.book_id = b.id
WHERE
    (status = 'PUBLISHED' OR status = 'PROMOTED')
    AND s.end_date >= DATE(NOW())
    AND e.is_private = FALSE
    AND s.id = t.show_id
    AND t.canceled = FALSE
GROUP BY  e.id,c.slug
ORDER BY  sold
LIMIT  30

此查询工作正常。我得到事件级聚合sold

TABLE ticket (
    id SERIAL PRIMARY KEY,
    book_id SERIAL REFERENCES books(id),
    order_id SERIAL REFERENCES purchases(id),
    show_id SERIAL REFERENCES shows(id),
    showtime character varying(10) NOT NULL,
    canceled boolean DEFAULT false
);

我想在此报告中添加另一个 sold 属性,在日期内。目前,日期条目如下所示:

[
  {
    "id": 46,
    "times": [
      {
        "end": "13:00",
        "start": "12:00"
      }
    ],
    "endDate": "2022-02-27",
    "daysAhead": 308,
    "startDate": "2022-02-27"
  },
  {
    "id": 46,
    "times": [
      {
        "end": "13:00",
        "start": "12:00"
      }
    ],
    "endDate": "2022-02-27",
    "daysAhead": 308,
    "startDate": "2022-02-27"
  }
]

我想聚合票务放映时间等于time.start,所以每个时间元素看起来除了开始和结束之外还有这个新的sold 属性。

我尝试使用 Postgres WITH 将当前查询变成一个集合,然后再次使用 JOIN ticket 表,但到目前为止没有太大成功。

基本上,我希望将时间分开并为它添加一个属性,例如每个事件的 COUNT(t.id),只过滤每个节目。

但是,嵌套聚合是不允许的,COUNT() 是一。

有什么建议吗?

【问题讨论】:

    标签: sql postgresql aggregate-functions


    【解决方案1】:

    与其将当前查询转换为with 语句并再次加入票证,不如采用另一种方式更容易,即在with 子句中使用票证表并将其加入当前查询。根据您的描述,我不确定您希望输出的样子,但可能类似于:

    WITH ticket_summary as(
       select book_id, count(1) as ticket_count
       from ticket
       group by book_id
    )
    SELECT
        e.id AS id, e.name AS name, e.description AS description,
        c.slug AS category,
        COUNT(t.id) AS sold,
        json_agg(json_build_object('id', b.id, 'title', b.title, 'description', b.description,'price', b.price, 'available', b.qty_available, 'qty_per_sale', b.qty_per_sale, 'sales', ts.ticket_count))::JSONB AS book, --can now use in aggregate
        json_agg(json_build_object('id', s.id, 'startDate', s.start_date, 'endDate', s.end_date,'daysAhead', (s.start_date::DATE - NOW()::DATE), 'times', s.times))::JSONB as dates
    FROM event e
        LEFT JOIN books b ON b.event_id = e.id
        LEFT JOIN shows s ON s.event_id = e.id
        LEFT JOIN category c ON e.category_id = c.id
        LEFT JOIN ticket t ON t.book_id = b.id
        --pull in summary data
        LEFT JOIN ticket_summary ts ON ts.book_id = b.id
    WHERE
        (status = 'PUBLISHED' OR status = 'PROMOTED')
        AND s.end_date >= DATE(NOW())
        AND e.is_private = FALSE
        AND s.id = t.show_id
        AND t.canceled = FALSE
    GROUP BY  e.id,c.slug
    ORDER BY  sold
    LIMIT  30
    

    【讨论】:

      猜你喜欢
      • 2022-01-20
      • 2013-08-19
      • 1970-01-01
      • 2019-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-13
      相关资源
      最近更新 更多