如何加入時間戳並包含 NULL 條目?
我正在嘗試查詢以將每日會計發票的總和與每日預算進行比較。預算儲存為一個月的一個值,因此我將該金額除以總天數,因為 4 月份將有 30 個條目。
但是,即使當天沒有發票,我也希望這些天的預算金額永久存在,無論是當天還是實際上當天。
我目前的查詢加入了時間戳的 date_part(‘day’,a.date) ,該時間戳僅在當天有發票時才會出現。我正在使用 PostgreSQL 版本 11.3。我已經嘗試了所有加入的可能性,並且每次都得到相同的結果。除非我使用 CROSS JOIN,它確實給出了所有 30 天,但每天所有發票的總和。我曾認為 FULL OUTER JOIN 會起作用,或者以其他方式使用 UNION ALL,但到目前為止我還沒有成功。
WITH RECURSIVE t(days,budget) AS (
SELECT 1 as days,b.amount/30 AS budget
FROM budgets b
WHERE b.id = 10
UNION ALL
SELECT t.days + 1,t.budget
FROM t WHERE t.days < 30)
SELECT
t.days AS "Day",
COALESCE ( SUM ( CASE WHEN a.account_id IN (17,43,44)
THEN a.credit - a.debit ELSE 0 END),0) AS "Invoices",
t.budget AS "Budget"
FROM t
LEFT JOIN accounting a
ON date_part('day',a.date) = t.days
WHERE a.date >= '2020-04-01'
AND a.date <= '2020-04-30'
AND a.account_id = 20
GROUP BY 1,3;
對於輸出,假設第 1 天、第 2 天和第 3 天已經過去,而第 2 天沒有條目。
目前產出
日發票預算
1 100 50
3 75 50
期望產出
日發票預算
1 100 50
2 0 50
3 75 50
4 0 50
5 0 50
…
30 0 50
我願意接受其他查詢想法來實現這一點。感謝您的幫助!
我已經設法做到了這一點,方法是從主查詢中完全刪除連接並創建一個 CASE WHEN 子查詢,如果匹配則首先查看,否則分配 0。然後,對符合條件的發票進行匯總。
如果有比我現在下面的查詢更好的方法來處理這個問題,請告訴我。由於我正在使用 CASE WHEN 和其中的子查詢,因此我認為這部分可以以某種方式更好地簡化。但是,如果它有效,它就有效並且看起來並不昂貴。
另外,請注意:上面我錯誤地引用了
a.account_id
第 18 行(倒數第二個)。當我將在我的情況下使用的確切表修改為更簡單的集合以理解所使用的 SQL 時,就會發生這種情況。確保我的會計表表示中的欄位:
a.account_id
= 代表會計科目表的
a.invoice_id
ID = 代表發票上銷售組的 ID(上面的錯誤a.account_id
是 20,應改為a.invoice_id
= 20)
a.credit
= 雙賬會計貸項
a.debit
= 雙賬會計借方
WITH RECURSIVE t(days,budget) AS (
SELECT 1 as days,b.amount/30 AS budget
FROM budgets b
WHERE b.id = 10
UNION ALL
SELECT t.days + 1,t.budget
FROM t WHERE t.days < 30)
SELECT
t.days AS "Day",
SUM ( CASE WHEN
( SELECT a.date FROM accounting a
LEFT JOIN t ON date_part('day',a.date) = t.days
WHERE a.date >= '2020-04-01'
AND a.date <= '2020-04-30'
AND a.invoice_id = 20
LIMIT 1) IS NULL
THEN 0 ELSE
( SELECT SUM
( CASE WHEN a.account_id IN (17,43,44)
THEN a.credit - a.debit ELSE 0 END)
FROM accounting a
WHERE date_part('day',a.date) = t.days
AND a.date >= '2020-04-01'
AND a.date <= '2020-04-30'
AND a.invoice_id = 20
)
END ) AS "Invoices",
t.budget AS "Budget"
FROM t
GROUP BY 1,3
ORDER BY 1;
我感謝那些看過這個查詢並考慮解決它的方法的人。