在 Postgres 中将 COUNT 与聚合一起使用
Using COUNT with aggregate in Postgres
我运行下面的查询来检索我的数据:
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
table 再次在其上,到目前为止没有太大成功。
基本上,我希望把时间分开,并在每个事件中添加一个 属性,如 COUNT(t.id),每个节目只过滤。
但是不允许嵌套聚合,COUNT()是一个。
有什么建议吗?
与其将当前查询变成 with
语句并再次加入票证,不如采用另一种方式更容易,即在 with
中使用票证 table ] 子句并将其加入当前查询。从你的描述中我不确定你想要输出的样子,但可能是这样的:
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
我运行下面的查询来检索我的数据:
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
table 再次在其上,到目前为止没有太大成功。
基本上,我希望把时间分开,并在每个事件中添加一个 属性,如 COUNT(t.id),每个节目只过滤。
但是不允许嵌套聚合,COUNT()是一个。
有什么建议吗?
与其将当前查询变成 with
语句并再次加入票证,不如采用另一种方式更容易,即在 with
中使用票证 table ] 子句并将其加入当前查询。从你的描述中我不确定你想要输出的样子,但可能是这样的:
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