我有兩個表:一個用于貨幣和圍繞它的屬性(例如誰獲得它)和一個用于“分類帳”的子表 - 這包含一個或多個代表已移動貨幣歷史的條目。
SELECT SUM(pl.achieved)
FROM payout p
LEFT JOIN payout_ledgers pl ON pl.payout_id = p.id
當只有一個分類帳專案時,此查詢效果很好,但當添加更多專案時,該查詢SUM會增加。我只想加入最新的一行。所以假設:
SELECT SUM(pl.achieved)
FROM payout p
LEFT JOIN payout_ledgers pl ON pl.payout_id = p.id ORDER BY pl.ts DESC LIMIT 1
WHERE ...
ORDER BY ...
LIMIT ...
(可悲的是不起作用)
我嘗試過的:
使用子查詢有效,但考慮到資料集的大小(以及其他省略的屬性和 where 子句等),速度非常慢:
SELECT SUM(pl.achieved)
FROM payout p
LEFT JOIN payout_ledgers pl ON pl.payout_id = p.id AND pl.id = (SELECT id FROM payout_ledgers WHERE payout_id = p.id ORDER BY ts DESC LIMIT 1)
順便說一句,我不確定為什么這個子查詢這么慢(大約 12 秒,而不是沒有子查詢的 150 毫秒)。鑒于我們僅根據外鍵 ( payout_id) 進行選擇,我原以為它會更快。
我嘗試的另一件事是從連接中進行選擇 - 我的邏輯是,如果我們從小的連接資料集而不是整個表中選擇它會更快。但是我遇到了relation "pl" does not exist錯誤:
SELECT SUM(pl.achieved)
FROM payouts p
LEFT JOIN payout_ledgers pl ON pl.payout_id = p.id
WHERE pl.id = (SELECT id FROM pl ORDER BY ts DESC LIMIT 1)
預先感謝您的任何建議。我也愿意接受可以使這種型別的邏輯更容易的架構更改建議,盡管我更喜歡嘗試讓查詢作業,因為架構在我們的生產環境中不容易更改。
uj5u.com熱心網友回復:
如果您使用的是 Postgres 9.4 ,則可以使用LEFT JOIN LATERAL( docs )
SELECT SUM(sub.achieved)
FROM payout p
LEFT JOIN LATERAL (SELECT achieved
FROM payout_ledgers pl
WHERE pl.payout_id = p.id
ORDER BY pl.ts DESC LIMIT 1) sub ON true
這將回傳所有支出的 payout_ledgers 中最新條目中“已實作”欄位的總和。
uj5u.com熱心網友回復:
視窗函式:
-- using row_number()
SELECT SUM(sss.achieved)
FROM (SELECT pl.achieved
, row_number() OVER (PARTITION BY pl.payout_id, ORDER BY pl.ts DESC)
FROM payouts p
JOIN payout_ledgers pl ON pl.payout_id = p.id
) sss
WHERE sss.rn =1
;
-- using last_value()
SELECT SUM(sss.achieved)
FROM (SELECT
, last_value(achieved) OVER (PARTITION BY pl.payout_id, ORDER BY pl.ts ASC) AS achieved
FROM payouts p
JOIN payout_ledgers pl ON pl.payout_id = p.id
) sss
;
順便說一句:您不需要LEFT JOIN (向 SUM 不添加任何值不會改變總和)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/328561.html
標籤:PostgreSQL
