簡體   English   中英

使用多個CASE語句時出錯[SQL]

[英]Errors when using multiple CASE statements [SQL]

在Microsoft SQL Server中使用SQL時,我遇到了一個非常具體的問題,即我要比較兩個月之間的數據。 此數據可以具有兩種狀態之一-為簡單起見,它可以是“ 1”或“ 0”,或者基本上是“是”或“否”。

我想考慮以下情況:

  • 如果某行在一個月內的狀態為“ 1”,而在下個月變為“ 0”, 反之亦然
  • 如果狀態沒有從一個月更改為另一個月(即“ 1”更改為“ 1”或“ 0”更改為“ 0”)
  • 如果狀態值在上個月為空,並且在下個月更改為“ 1”或“ 0”

我假設我可以為此使用多個CASE語句,到目前為止,在遇到問題之前,我得到的是以下內容:

select
     --determine if status changes from 1 to 0 between two months or stays the same
     case
     when T.[status] = '1' and T.date between '01-01-2017' and '02-28-2017'
     then 'No Change'
     else
     'Status Changed to 0'
     end,

     --determine if status changes from 0 to 1 between two months or stays the same
     case
     when T.[status] = '0' and T.date between '01-01-2017' and '02-28-2017'
     then 'No Change'
     else 
     'Status Changed to 1'
     end,

     --determine if there was new row that didn't appear in first month with a status of 1 or 0 in second month
     case
     when T.status is null in T.date between '01-01-2017' and '01-31-2017'  
     and T.status = '1' in T.date between '02-01-2017' and '02-28-2017' then 'New Status to 1'
     else
     'New Status of 1'
     end, *
from table T
where ....

該代碼適用於第一個CASE語句,以在新列中顯示從1到0的狀態更改,但是它使第二列顯示另一狀態,因此我不確定它是否按預期工作。 而且,由於我正在一起檢查兩個月,因此我似乎無法邏輯地將其他方案編碼到我的SQL中。

我試圖找到一種方法來壓縮所有CASE語句,使其僅產生一個額外的列,而我遇到的另一個問題是,第三條CASE語句在第一個“ IN”處引發了語法錯誤。 希望這對某人有意義,並在此先感謝您提供的任何輸入或技巧。

首先考慮最后一個問題,即“ IN”的不正確語法:

 case
 when T.status is null in t.date between '01-01-2017' and '01-31-2017'  
 and T.status = '1' in T.date between '02-01-2017' and '02-28-2017' then 'New Status to 1'
 else
 'test'
 end

嘗試:

 case
 when (T.status is null AND t.date between '01-01-2017' and '01-31-2017')  
 OR (T.status = '1' AND T.date between '02-01-2017' and '02-28-2017') then 'New Status to 1'
 else
 'test'
 end

為了更輕松地檢查狀態更改,請以一個月的補償將表連接到自身。

我在WITH子句中添加了帶有輸入數據的示例表,它可以滿足您的要求。 我正在使用SQL Server支持的LAG()分析函數。 請記住,在分析窗口分區的第一行中,LAG()返回NULL-因為在這種情況下沒有前一行。

在SQL Server以外的其他DBMS中,您將需要ANSI串聯運算符|| 而不是+來連接兩個字符串。

WITH
input(input_id,monthfirst,status) AS (
          SELECT 1,DATE '2017-01-01',0
UNION ALL SELECT 1,DATE '2017-02-01',1
UNION ALL SELECT 1,DATE '2017-03-01',0
UNION ALL SELECT 2,DATE '2017-01-01',1
UNION ALL SELECT 2,DATE '2017-02-01',1
UNION ALL SELECT 2,DATE '2017-03-01',0
UNION ALL SELECT 3,DATE '2017-01-01',CAST(NULL AS INT)
UNION ALL SELECT 3,DATE '2017-02-01',1
UNION ALL SELECT 3,DATE '2017-03-01',0
)
,
input_with_prev_status AS (
SELECT
  *
, LAG(status) OVER (PARTITION BY input_id ORDER BY monthfirst) AS prev_status
FROM input
)
SELECT
  input_id
, monthfirst
, status
, CASE
    WHEN prev_status IS NULL AND status IS NOT NULL
      THEN 'New status to ' + CAST(status AS CHAR(1))
    WHEN prev_status <> status
      THEN 'Status changed to ' + CAST(status AS CHAR(1))
    WHEN prev_status = status
      THEN 'no status change'
    WHEN prev_status IS NULL AND status IS NULL
      THEN 'status remains missing'
    ELSE 'unforeseen status change'
  END AS status_change
FROM input_with_prev_status
;
input_id|monthfirst|status|status_change
       1|2017-01-01|     0|New status to 0
       1|2017-02-01|     1|Status changed to 1
       1|2017-03-01|     0|Status changed to 0
       2|2017-01-01|     1|New status to 1
       2|2017-02-01|     1|no status change
       2|2017-03-01|     0|Status changed to 0
       3|2017-01-01|-     |status remains missing
       3|2017-02-01|     1|New status to 1
       3|2017-03-01|     0|Status changed to 0

請參見下面的自我連接代碼(由Dejan建議)。 您需要使用表T中的鍵列創建ON語句

select 
  case 
  when (T1.[status] = '1' and T2. [status] = '1') or (T1.[status] = '0' and T2. [status] = '0') then 'No Change'
  when T1.[status] = '1' and T2. [status] = '0' then 'Status Changed to 0'
  when T1.[status] = '0' and T2. [status] = '1' then 'Status Changed to 1'
  when T.status is null and  T2. [status] = '1' then 'New Status to 1'
 else
 'test'
  end
table T1 
inner join T2
   on ....join on the key column
where T1.date between '01-01-2017' and '31-01-2017' 
and T2.date between '01-02-2017' and '28-02-2017'

暫無
暫無

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

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