在SQL Server的CASE语句中使用COUNT(*)

时间:2019-06-04 10:13:31

标签: sql sql-server tsql

是否可以在T-SQL的case语句中使用count(*)? 我正在尝试更新表中的记录,但我希望有2种情况。

第一种情况应在EndDate小于StartDate时进行更新,第二种情况应仅在我具有特定EmployeeId的确切记录时进行更新。

update ep
set ep.EndDate = case when t.EndDate < t.StartDate then t.EndDate3
                 case when COUNT(*) = 1 then null
end ,ep.ModifiedBy = 'PCA', ep.ModifiedDate = getdate()
from dbo.EmployeeProductivity ep inner join cteT1 t
on ep.Id = t.Id
where t.EndDate < t.StartDate
or t.EndDate is null

我正在尝试类似的操作,但出现类似以下错误:

an expression of non boolean type specified in a context where a condition is expected

这是完整的脚本:

use ws3;

select distinct (EmployeeId) as EmployeeId
  into #Emps
  from [dbo].[EmployeeProductivity]
 where EndDate < StartDate
    or EndDate is null;

with cteProdRates as 
(
    select  ep.[ID]
           ,ep.[EmployeeId]
           ,ep.[FormatId]
           ,ep.[StartDate]
           ,ep.[EndDate]
           ,dateadd(dd, -1, lag(startdate) over (partition by ep.EmployeeId, FormatId order by StartDate desc, Id desc)) as EndDate2
           ,ep.[Rate]
      FROM [dbo].[EmployeeProductivity] ep inner join #Emps e
        on ep.EmployeeId = e.EmployeeId
)
,cteT1 as
(
   select [ID]
         ,[EmployeeId]
         ,[FormatId]
         ,[StartDate]
         ,[EndDate]
         ,case when EndDate2 < StartDate then StartDate else EndDate2 end as EndDate3
         ,[Rate]
    from cteProdRates
)

update ep
   set ep.EndDate = case when t.EndDate < t.StartDate then t.EndDate3
                    case when COUNT(*) = 1 then null
   end ,ep.ModifiedBy = 'PCA', ep.ModifiedDate = getdate()
  from dbo.EmployeeProductivity ep inner join cteT1 t
    on ep.Id = t.Id
 where t.EndDate < t.StartDate
    or t.EndDate is null

drop table #Emps

因此,对于每个唯一的EmployeeId,我都有多个条目。每个StartDate必须大于EndDate,并且当使用新的StartDate添加新条目时,上一个条目EndDate设置为newEntry.StartDate-1。仅当条目是最后一个条目时,EndDate设置为NULL,这意味着该条目不是已关闭。

这就是为什么当我只有一个条目用于特定EmployeeId时需要检查大小写,因此我可以将其设置为NULL。

这甚至可以比较吗?或者我缺少什么?有人对此有经验吗?

1 个答案:

答案 0 :(得分:2)

您不能在count(*)中使用update。这与case 表达式无关。

也许这就是您想要的:

update ep
    set ep.EndDate = (case when t.EndDate < t.StartDate then t.EndDate3
                           when cnt = 1 then null
                      end),
        ep.ModifiedBy = 'PCA',
        ep.ModifiedDate = getdate()
from dbo.EmployeeProductivity ep inner join
     (select t.*, count(*) over (partition by id) as cnt
      from cteT1 t
      where t.EndDate < t.StartDate or t.EndDate is null
     ) t
     on ep.Id = t.Id

当然,正如逻辑上所说的那样,count()上的条件是多余的– case expression 无论如何都会返回NULL,因此此逻辑似乎是等效的:

update ep
    set ep.EndDate = (case when t.EndDate < t.StartDate then t.EndDate3
                      end),
        ep.ModifiedBy = 'PCA',
        ep.ModifiedDate = getdate()
from dbo.EmployeeProductivity ep inner join
     from cteT1 t
     on ep.Id = t.Id
where t.EndDate < t.StartDate or t.EndDate is null