[英]SQL: look up value in a different table if a given condition is met
我有兩個包含相關數據的 SQL 表,我需要進行條件查找,我主要在主表中查找值,但如果滿足主表中的某個條件,我 go 另外到第二個表。
表格看起來像這樣(為難看的格式道歉):
主要的
subscription_id | 地位 | 開始 | 結尾 |
---|---|---|---|
1個 | 積極的 | 2020-1-1 | 2022-12-1 |
2個 | 取消 | 2020-1-1 | 2022-12-1 |
歷史
subscription_id | 地位 | 日期 |
---|---|---|
1個 | 積極的 | 2020-1-1 |
2個 | 積極的 | 2020-1-1 |
2個 | 取消 | 2021-4-1 |
我想查找在給定日期哪些訂閱處於活動狀態。 MAIN 表給出了訂閱的開始和結束日期及其當前狀態。 但是,如果訂閱被取消,它不會顯示實際取消日期,只會顯示原始結束日期。 HISTORY 表顯示訂閱狀態的所有更改,包括取消。 例如,訂閱 2 創建於 2020-1-1,原定於 2022-12-1 到期,但於 2021-4-1 取消。
所以我需要做的是 select 來自 MAIN 的所有訂閱,其開始和結束日期包含我感興趣的日期,但如果訂閱狀態為 Canceled,我需要在 HISTORY 中查找它,如果日期在它的“已取消”行晚於我感興趣的日期。
我正在嘗試使用 UNION 語句來執行此操作,首先僅從 MAIN 中選擇活動訂閱,然后根據 HISTORY 中的取消日期選擇已取消的訂閱。 例如,如果感興趣的日期是 2022-1-1:
(SELECT subscription_id from Main
WHERE status = 'Active' AND start <= '2022-1-1' AND end >= '2022-1-1')
UNION
(SELECT m.subscription_id from Main m
JOIN
(SELECT * from History
WHERE status = 'Canceled' AND date > '2022-1-1') h
ON m.subscription_id = h.subscription_id
WHERE m.status = 'Canceled' AND start <= '2022-1-1' AND end >= '2022-1-1')
這可以運行,但我對 SQL 沒有經驗,並且不確定它是否符合我的要求 - 邏輯是否合理?
或者,根據 Jonas Metzler 在評論中的建議,我提出了一種不同的方法,它基本上嘗試重新創建主表,但如果訂閱被取消,則從歷史記錄中獲取結束日期:
WITH cte AS (SELECT * FROM history WHERE status='Canceled')
SELECT m.subscription_id, m.status, start,
(CASE WHEN m.status='Canceled' THEN cte.date else m.end) as end
FROM main m
LEFT JOIN cte ON m.subscription_id = cte.subscription_id
然后我可以使用這個新表來查找特定日期。 同樣,我不完全確定這是否符合我的意圖,因此最好進行完整性檢查。
這是一個訂閱業務model的用例,它的生命周期狀態有Active
, Canceled
, Expired
...等。 而且,它應該有一個續訂過程來更新MAIN.end
列中的到期日期。 所有狀態變化都應記錄在HISTORY
表中(通常與法律要求有關)。 考慮到這一點,
set @some_date = '2020-03-01';
with cte_subscription as (
select subscription_id,
status,
date as start_date,
lead(date,1) over (partition by subscription_id order by date) as end_date
from history)
select *
from cte_subscription
where @some_date >= start_date
and @some_date <= COALESCE(end_date, '9999/12/31');
結果:
subscription_id|status|start_date|end_date |
---------------+------+----------+----------+
1|Active|2020-01-01| |
2|Active|2020-01-01|2020-04-01|
讓我們將日期更改為:
set @some_date = '2020-05-01';
結果:
subscription_id|status |start_date|end_date|
---------------+--------+----------+--------+
1|Active |2020-01-01| |
2|Canceled|2020-04-01| |
順便說一句,如果它超過了訂閱的到期日期,則HISTORY
表應該如下所示:
subscription_id|status |date |
---------------+--------+----------+
1|Active |2020-01-01| <-- Subscription started
2|Active |2020-01-01|
2|Canceled|2020-04-01| <-- Subscription cancelled
1|Expired |2022-12-01| <-- Subscription expired
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.