sqlfiddle
select *
from example;
edate userid status
2022-05-01 abc123 true
2022-05-02 abc123 (null)
2022-05-03 abc123 (null)
2022-05-04 abc123 (null)
2022-05-05 abc123 false
2022-05-06 abc123 (null)
2022-05-07 abc123 (null)
2022-05-08 abc123 (null)
2022-05-09 abc123 true
2022-05-10 abc123 (null)
我想根據 userId 的最新資料點撰寫一個新欄位“status_backfilled”。
在示例資料中,用戶狀態在 5 月 1 日為真,然后在 5 月 5 日之前為空。因此,我希望新欄位在 5 月 1 日至 5 月 4 日期間為真。然后狀態切換為假。這個值在 5 月 9 日之前保持不變,所以我希望在 5 月 5 日到 8 日之間為 false,然后再次為 true。
期望的輸出:
select *
from example_desired;
edate userid status_backfilled
2022-05-01 abc123 true
2022-05-02 abc123 true
2022-05-03 abc123 true
2022-05-04 abc123 true
2022-05-05 abc123 false
2022-05-06 abc123 false
2022-05-07 abc123 false
2022-05-08 abc123 false
2022-05-09 abc123 true
2022-05-10 abc123 true
如何按列合并以獲取對資料進行排序的用戶的最新非空狀態,在這種情況下按日期排序?
uj5u.com熱心網友回復:
實際上,甚至更好:
select e1.edate, e1.userId, coalesce(e1.status, t.status) as status
from example e1
cross join lateral (
select status from example e2
where e1.userid = e2.userid
and e1.edate > e2.edate
and e2.status is not null
order by e2.edate desc limit 1
) t
小提琴
這是另一種方式:
with cte as (
select e.* ,e_s.edate s_edate, e_s.status s_status , row_number() over (partition by e.userid,e.edate order by e_s.edate desc) rn
from example e
left join (
select *
from example
where status is not null
) e_s on e.userid = e_s.userid
and e_s.edate < e.edate
)
select edate, userId, coalesce(status, s_status) as status
from cte where rn = 1
uj5u.com熱心網友回復:
您可以通過使用一些視窗函式來實作您想要的結果 -
WITH grp AS (SELECT edate, userid, status,
CASE WHEN status IS NULL THEN 0
ELSE ROW_NUMBER() OVER(ORDER BY edate)
END RN
FROM example
),
grp_sum AS (SELECT edate, userid, status, SUM(RN) OVER(ORDER BY edate) grp_sum
FROM grp
)
SELECT edate, userid,
FIRST_VALUE(status) OVER(PARTITION BY grp_sum ORDER BY status NULLS LAST) status_backfilled
FROM grp_sum;
演示。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/484230.html
標籤:sql PostgreSQL
上一篇:從“通過擁有組”查詢中查找單個值
