使用多个 CASE 语句 [SQL] 时出错



在Microsoft SQL Server中使用SQL,我有一个非常具体的问题,即我比较两个月的数据。此数据可以具有以下两种状态之一 - 为简单起见,它要么是"1"或"0",要么基本上是"是"或"否"。

我想考虑以下情况:

  • 如果一行在一个月内的状态为"1",下个月变为"0",反之亦然
  • 如果状态没有从一个月更改为另一个月(即"1"到"1"或"0"到"0")
  • 如果状态值在上个月为 null,并在下个月更改为"1"或"0">

我假设我可以为此使用多个 CASE 语句。此外,由于我正在一起检查这两个月,我似乎无法将其他场景编码到我的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'

相关内容

  • 没有找到相关文章

最新更新