带分区的案例陈述

Case statement with partition

我必须根据以下条件更新每个 ID 的状态。 一个ID可以有多个状态,但我必须根据条件选择状态。

我的示例架构如下:

CREATE TABLE [dbo].[Table1](
    [ID] [nvarchar](50) NULL,
    [ApprovalDate] [datetime] NULL,
    [CreateDate] [datetime] NULL,   
    [status] [nvarchar](50) NULL
) 
;
Insert into Table1 values (1,null,null,'Approved')
Insert into Table1 values (1,null,null,'Modified')
Insert into Table1 values (1,null,null,'Later')
Insert into Table1 values (2,null,null,'Approved')
Insert into Table1 values (2,null,null,'Modified')
Insert into Table1 values (2,null,null,'Approved')
Insert into Table1 values (3,null,null,'Modified')
Insert into Table1 values (3,null,null,'Later')
Insert into Table1 values (4,null,null,'Approved')

如果 ID 1 已批准,稍后修改,我应该说 "Partially Modified",如果 ID 已批准和修改,那么也 "Partially Modified"。但是我得到的案例陈述不是按照 ID.It 正在根据 status.Please 建议更改整体数据。我包含了 SQL 提琴手,输出应该有 ID 1 - 部分修改,2-部分修改,3-修改,4-批准 .. 行数与 table ..

select ID,
   CASE
      WHEN status = 'Approved' AND status IN('Modified','Later') 
         THEN 'Partial Modified'
      WHEN status = 'Approved' 
         THEN 'Approved'
      WHEN status IN('Modified','Edited') THEN 'Modified'
      ELSE status
      END status 
 group by ID,Status

http://sqlfiddle.com/#!18/9bf47/7/0

下面是一个可能的解决方案。

SELECT ID,
   CASE WHEN MAX( CASE WHEN [status] = 'Approved' THEN 'Approved' ELSE NULL END ) = 'Approved'
            AND MAX( CASE WHEN [status] IN('Modified','Later') THEN 'Partial Modified' ELSE NULL END ) = 'Partial Modified'
        THEN 'Partial Modified'
        ELSE MAX([status]) -- this can go wrong if there are multiple status which don't fall into above condition.
        END AS [Status]     
FROM Table1
GROUP BY ID

方法:2 如果您想要与 table 中相同行数的结果,请使用以下查询。

;WITH CTE AS (
    SELECT ID,
       CASE WHEN MAX( CASE WHEN [status] = 'Approved' THEN 'Approved' ELSE NULL END ) = 'Approved'
                AND MAX( CASE WHEN [status] IN('Modified','Later') THEN 'Partial Modified' ELSE NULL END ) = 'Partial Modified'
            THEN 'Partial Modified'
            WHEN MAX( CASE WHEN [status] = 'Modified' THEN 'Modified' ELSE NULL END ) = 'Modified'
                AND MAX( CASE WHEN [status] IN('Edited','Later') THEN 'Modified' ELSE NULL END ) = 'Modified'
            THEN 'Modified'
            ELSE NULL -- this can go wrong if there are multiple status which don't fall into above condition.
            END AS [Status]     
    FROM Table1
    GROUP BY ID
) 
SELECT 
    t.ID,
    ISNULL(c.[status],t.[status]) AS [status]
FROM CTE AS c
INNER JOIN Table1 AS t ON t.ID = c.ID
GROUP BY t.ID, t.[status],c.[status]

输出

ID      status
------- ----------------
1       Partial Modified
1       Partial Modified
1       Partial Modified
2       Partial Modified
2       Partial Modified
3       Modified
3       Modified
4       Approved

您可以使用如下查询。 请注意,这种方法允许您 pre-map 所有用例作为整数值的简单组合,而不是像 WHEN status = 'Approved' AND status IN('Modified','Later')

这样的复杂案例表达式

See live demo

select id,
case sum(v) 
    when 1 then 'approved'
    when 2 then 'modified'
    when 3 then 'partially modified'
    when 4 then 'partially modified'
    when 5 then 'partially modified'
    when 6 then 'modified'
    when 7 then 'partially modified'
end [status] from
Table1 t1 join
 (values( 'approved',1),('Modified',2),('later',4)) as t(s,v)
 on t1.[status]=t.s
 group by id

want the ID row to repeat with the same final status

所以在那种情况下解决方案将是

select 
T1.*,
T.[status]

from
Table1 T1
Join
(
    select id,
    case sum(v) 
        when 1 then 'approved'
        when 2 then 'modified'
        when 3 then 'partially modified'
        when 4 then 'partially modified'
        when 5 then 'partially modified'
        when 6 then 'modified'
        when 7 then 'partially modified'
    end [status] from
    Table1 t1 join
     (values( 'approved',1),('Modified',2),('later',4)) as t(s,v)
     on t1.[status]=t.s
     group by id
)T
on T.id=T1.id