Postgres - 简化基于日期的 select 子查询的重复
Postgres - simplify repeat of select subqueries based on dates
Postgres (9.6) 新手。
我有 2 table
sales_account(客户列表)
日记帐(交易行发票付款)
我想创建另一个名为 balances 的 table,它具有基于时间段(如 7 天、14 天、30 天、60 天或更早)的未结交易摘要。
我已将查询作为子查询详细编写(生成时间太长 - 有超过 1500 万条日志记录)但我正在寻找有关如何简化查询的任何提示。
谢谢。
INSERT INTO balances (sales_account,
balance,
period_1,
period_2,
period_3,
period_4,
period_5)
SELECT sales_account.id,
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active'), -- overall balance
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.reversed_by is null AND
journal.original_id is null AND
journal.transaction_date <= CURRENT_DATE - interval '7 days'), -- current
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.reversed_by is null AND
journal.original_id is null AND
journal.transaction_date <= CURRENT_DATE - interval '14 days' AND
journal.transaction_date >= CURRENT_DATE - interval '8 days'), -- 8-14 days
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.transaction_date <=CURRENT_DATE - interval '30 days' AND
journal.transaction_date >= CURRENT_DATE - interval '15 days'), -- 22-30 days
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.transaction_date >= CURRENT_DATE - interval '31 days' AND
journal.transaction_date <=CURRENT_DATE - interval '60 days'), -- 31-60 days
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.transaction_date >= CURRENT_DATE - interval '61 days') -- 61+ days
FROM sales_account;
这可以简化为一个查询,使用案例:
SELECT
coalesce(sum(case
when journal.transaction_date >= CURRENT_DATE - interval '8 days' AND
journal.transaction_date <= CURRENT_DATE - interval '14 days'
then
journal.outstanding else 0
end),0) days814,
coalesce(sum(case
when journal.transaction_date >= CURRENT_DATE - interval '22 days' AND
journal.transaction_date <= CURRENT_DATE - interval '30 days'
then
journal.outstanding else 0
end),0) days2230,
coalesce(sum(case
when journal.transaction_date >= CURRENT_DATE - interval '31 days' AND
journal.transaction_date <= CURRENT_DATE - interval '60 days'
then
journal.outstanding else 0
end),0) days3160,
coalesce(sum(case
when journal.transaction_date >= CURRENT_DATE - interval '61 days'
then
journal.outstanding else 0
end),0) days61,
FROM journal, sales_account
WHERE journal.sales_account = sales_account.id AND
journal.status='Active'
您可以使用 FILTER 表达式来简化 SUM
:
INSERT INTO balances (sales_account,
balance,
period_1,
period_2,
period_3,
period_4,
period_5)
SELECT
COALESCE(sum(journal.outstanding), 0) AS overall,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '7 days'
AND journal.reversed_by IS NULL
AND journal.original_id IS NULL), 0) AS period_1,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '14 days'
AND journal.transaction_date <= CURRENT_DATE - interval ' 8 days'
AND journal.reversed_by IS NULL
AND journal.original_id IS NULL), 0) AS period_2,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '30 days'
AND journal.transaction_date <= CURRENT_DATE - interval '22 days'), 0) AS period_3,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '60 days'
AND journal.transaction_date <= CURRENT_DATE - interval ' 31 days'), 0) AS period_4,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '61 days'), 0) AS period_5
FROM
journal
JOIN sales_account ON (journal.sales_account = sales_account.id)
WHERE
journal.status='Active';
Postgres (9.6) 新手。
我有 2 table
sales_account(客户列表)
日记帐(交易行发票付款)
我想创建另一个名为 balances 的 table,它具有基于时间段(如 7 天、14 天、30 天、60 天或更早)的未结交易摘要。
我已将查询作为子查询详细编写(生成时间太长 - 有超过 1500 万条日志记录)但我正在寻找有关如何简化查询的任何提示。
谢谢。
INSERT INTO balances (sales_account,
balance,
period_1,
period_2,
period_3,
period_4,
period_5)
SELECT sales_account.id,
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active'), -- overall balance
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.reversed_by is null AND
journal.original_id is null AND
journal.transaction_date <= CURRENT_DATE - interval '7 days'), -- current
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.reversed_by is null AND
journal.original_id is null AND
journal.transaction_date <= CURRENT_DATE - interval '14 days' AND
journal.transaction_date >= CURRENT_DATE - interval '8 days'), -- 8-14 days
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.transaction_date <=CURRENT_DATE - interval '30 days' AND
journal.transaction_date >= CURRENT_DATE - interval '15 days'), -- 22-30 days
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.transaction_date >= CURRENT_DATE - interval '31 days' AND
journal.transaction_date <=CURRENT_DATE - interval '60 days'), -- 31-60 days
(SELECT coalesce(sum(journal.outstanding),0)
FROM journal
WHERE journal.sales_account = sales_account.id AND
journal.status='Active' AND
journal.transaction_date >= CURRENT_DATE - interval '61 days') -- 61+ days
FROM sales_account;
这可以简化为一个查询,使用案例:
SELECT
coalesce(sum(case
when journal.transaction_date >= CURRENT_DATE - interval '8 days' AND
journal.transaction_date <= CURRENT_DATE - interval '14 days'
then
journal.outstanding else 0
end),0) days814,
coalesce(sum(case
when journal.transaction_date >= CURRENT_DATE - interval '22 days' AND
journal.transaction_date <= CURRENT_DATE - interval '30 days'
then
journal.outstanding else 0
end),0) days2230,
coalesce(sum(case
when journal.transaction_date >= CURRENT_DATE - interval '31 days' AND
journal.transaction_date <= CURRENT_DATE - interval '60 days'
then
journal.outstanding else 0
end),0) days3160,
coalesce(sum(case
when journal.transaction_date >= CURRENT_DATE - interval '61 days'
then
journal.outstanding else 0
end),0) days61,
FROM journal, sales_account
WHERE journal.sales_account = sales_account.id AND
journal.status='Active'
您可以使用 FILTER 表达式来简化 SUM
:
INSERT INTO balances (sales_account,
balance,
period_1,
period_2,
period_3,
period_4,
period_5)
SELECT
COALESCE(sum(journal.outstanding), 0) AS overall,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '7 days'
AND journal.reversed_by IS NULL
AND journal.original_id IS NULL), 0) AS period_1,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '14 days'
AND journal.transaction_date <= CURRENT_DATE - interval ' 8 days'
AND journal.reversed_by IS NULL
AND journal.original_id IS NULL), 0) AS period_2,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '30 days'
AND journal.transaction_date <= CURRENT_DATE - interval '22 days'), 0) AS period_3,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '60 days'
AND journal.transaction_date <= CURRENT_DATE - interval ' 31 days'), 0) AS period_4,
COALESCE(sum(journal.outstanding)
FILTER (WHERE journal.transaction_date >= CURRENT_DATE - interval '61 days'), 0) AS period_5
FROM
journal
JOIN sales_account ON (journal.sales_account = sales_account.id)
WHERE
journal.status='Active';