簡體   English   中英

如何在 sql where 條件中使用 case 語句

[英]how to use a case statement in a sql where condition

我有以下格式的 sql:

select distinct
      ora_hash( ah.target_name 
                   || to_char( start_timestamp, 'DD-MON-YY HH24:MI:SS' ))
         || ','
         || 'Critical'
         || ','
         || host_name
         || ','
         || ah.target_name
         || ','
         || 'Instance unexpectedly shutdown at '
         || to_char( start_timestamp, 'DD-MON-YY HH24:MI:SS' )
   from 
      sysman_ro.mgmt$availability_history ah
         join sysman_ro.mgmt$target_members tm 
            on ah.target_name = tm.member_target_name
         join sysman_ro.mgmt$target mt 
            on ah.target_name = mt.target_name
            left outer join sysman_ro.mgmt$blackout_history bh  
               on mt.target_name = bh.target_name
   where 
          tm.aggregate_target_name like 'PROD_DB'
      and ah.availability_status_code = 0
      and ah.start_timestamp > sysdate -0.2
      and ah.start_timestamp > bh.start_time
      and ah.target_type = 'oracle_database'

現在的問題是 bh.start_time 不會為少數目標返回任何內容。 所以在這里我想引入一個 case 語句,如果 bh.start_time 有一個值(比如 08-NOV-22),那么應該考慮條件 'ah.start_timestamp > bh.start_time' 並且如果沒有返回值對於 bh.start_time 那么應該跳過條件 'ah.start_timestamp > bh.start_time'。

在'where'條件下這可能嗎? 謝謝。

這不是CASE語句,它只是一個OR條件。 例如:

AND (bh.start_time IS NULL OR ah.start_timestamp > bh.start_time)

因此,如果start_timeNULLstart_timestamp > start_time ,則總體條件得到滿足。

首先 - CASE 是一個表達式(不是語句)。 它連續工作,第一個WHEN條件為True將返回THEN退出CASE 這意味着您應該以一種能夠給出您想要的結果的方式對這些條件進行排序。
一個小樣本數據(我們不知道你的數據):

WITH
    ah AS
        (
            Select 1 "AH_ID", To_Date('08.11.2022 13:00:00', 'dd.mm.yyyy hh24:mi:ss') "AH_DATE" From Dual Union All
            Select 2 "AH_ID", To_Date('08.11.2022 16:00:00', 'dd.mm.yyyy hh24:mi:ss') "AH_DATE" From Dual Union All
            Select 3 "AH_ID", To_Date('08.11.2022 19:00:00', 'dd.mm.yyyy hh24:mi:ss') "AH_DATE" From Dual Union All
            Select 4 "AH_ID", To_Date('08.11.2022 22:00:00', 'dd.mm.yyyy hh24:mi:ss') "AH_DATE" From Dual Union All
            Select 5 "AH_ID", To_Date('08.11.2022 23:00:00', 'dd.mm.yyyy hh24:mi:ss') "AH_DATE" From Dual 
        ),
    bh AS
        (
            Select 1 "BH_ID", 1 "AH_ID", To_Date('08.11.2022 07:00:00', 'dd.mm.yyyy hh24:mi:ss') "BH_DATE" From Dual Union All
            Select 2 "BH_ID", 1 "AH_ID", To_Date('08.11.2022 09:00:00', 'dd.mm.yyyy hh24:mi:ss') "BH_DATE" From Dual Union All
            Select 3 "BH_ID", 3 "AH_ID", To_Date('08.11.2022 19:00:00', 'dd.mm.yyyy hh24:mi:ss') "BH_DATE" From Dual Union All
            Select 4 "BH_ID", 3 "AH_ID", To_Date('08.11.2022 20:00:00', 'dd.mm.yyyy hh24:mi:ss') "BH_DATE" From Dual Union All
            Select 5 "BH_ID", 5 "AH_ID", To_Date('08.11.2022 21:00:00', 'dd.mm.yyyy hh24:mi:ss') "BH_DATE" From Dual 
        )

如果我們離開加入桌子,如果它就像
SYSDATE = To_Date('09.11.2022 01:00:00', 'dd.mm.yyyy hh24:mi:ss')
我選擇 SYSDATE_LIMIT 列只是為了能夠直觀地比較稍后將過濾的值:

Select
    ah.AH_ID, 
    To_Char(ah.AH_DATE, 'dd.mm.yyyy hh24:mi:ss') "AH_DATE",
  To_Char(To_Date('09.11.2022 01:00:00', 'dd.mm.yyyy hh24:mi:ss') - 0.2, 'dd.mm.yyyy hh24:mi:ss') "SYSDATE_LIMIT",
    bh.BH_ID, 
    To_Char(bh.BH_DATE, 'dd.mm.yyyy hh24:mi:ss') "BH_DATE"
From
    ah
Left Join
    bh ON(bh.AH_ID = ah.AH_ID)

結果是:

AH_ID AH_DATE SYSDATE_LIMIT BH_ID BH_DATE
1個 08.11.2022 13:00:00 08.11.2022 20:12:00 1個 08.11.2022 07:00:00
1個 08.11.2022 13:00:00 08.11.2022 20:12:00 2個 08.11.2022 09:00:00
2個 08.11.2022 16:00:00 08.11.2022 20:12:00
3個 08.11.2022 19:00:00 08.11.2022 20:12:00 3個 08.11.2022 19:00:00
3個 08.11.2022 19:00:00 08.11.2022 20:12:00 4個 08.11.2022 20:00:00
4個 08.11.2022 22:00:00 08.11.2022 20:12:00
5個 08.11.2022 23:00:00 08.11.2022 20:12:00 5個 08.11.2022 21:00:00

使用 CASE 表達式在 WHERE 子句中進行過濾的方法之一可能就像這里(代碼中的注釋)

... ... ...
Where
    CASE 
        WHEN bh.BH_ID Is Null THEN 0            -- there is no matching row in bh table - excluded
        WHEN ah.AH_DATE <= bh.BH_DATE THEN 0        -- AH_DATE is not greater than BH_DATE - excluded
        WHEN ah.AH_DATE <= To_Date('09.11.2022 01:00:00', 'dd.mm.yyyy hh24:mi:ss') - 0.2 THEN 0  -- AH_DATE is not greater than SYSDATE - 0.2 - excluded
    ELSE 1      -- there is a row in bh table where AH_DATE is greater than BH_DATE and AH_DATE is greater than SYSDATE - 0.2   -  row returned
    END = 1

結果:

AH_ID AH_DATE SYSDATE_LIMIT BH_ID BH_DATE
5個 08.11.2022 23:00:00 08.11.2022 20:12:00 5個 08.11.2022 21:00:00

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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