簡體   English   中英

SQL:如果滿足給定條件,則在不同的表中查找值

[英]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的用例,它的生命周期狀態有ActiveCanceledExpired ...等。 而且,它應該有一個續訂過程來更新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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM