简体   繁体   English

在 Postgres 中使用 COUNT 和聚合

[英]Using COUNT with aggregate in Postgres

I am running the below query to retrieve my data:我正在运行以下查询来检索我的数据:

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

This query works fine.此查询工作正常。 I get event-level aggregate sold .我得到了事件级别的聚合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
);

I want to add another sold property to this report, inside dates.我想在此报告中添加另一个sold的房产,日期内。 Currently, dates entry looks like:目前,日期条目如下所示:

[
  {
    "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"
  }
]

I want to aggregate on ticket showtime being equal to time.start , so each times element would look have this new sold property in addition to start and end.我想汇总票证放映时间等于time.start ,因此每个时间元素看起来除了开始和结束之外还有这个新的sold属性。

I tried using Postgres WITH to turn the current query into a set, then JOIN the ticket table on it again, without much success so far.我尝试使用 Postgres WITH将当前查询转换为一个集合,然后再次在其上JOIN ticket表,到目前为止没有太大成功。

Basically, I wish to just take times apart and add a property to it like COUNT(t.id) per event, only filtered per show.基本上,我希望只花时间分开并向它添加一个属性,例如每个事件的 COUNT(t.id),只在每个节目中过滤。

However, nested aggregations are not allowed, and COUNT() is one.但是,不允许嵌套聚合,并且 COUNT() 是一。

Any suggestions?有什么建议么?

Rather than turn the current query into a with statement and joining to tickets again, it may be easier to go the other way, ie use the ticket table in a with clause and join that to the current query.与其将当前查询转换为with语句并再次加入票证,不如以另一种方式更容易 go,即在with子句中使用票证表并将其加入当前查询。 I'm not sure from your description exactly what you want the output to look like, but perhaps something like:从您的描述中,我不确定您希望 output 看起来像什么,但可能类似于:

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

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

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