【问题标题】:Using COUNT(*) inside CASE statement in SQL Server在 SQL Server 的 CASE 语句中使用 COUNT(*)
【发布时间】:2019-06-04 18:41:19
【问题描述】:

是否可以在 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。

这甚至可以比较还是我错过了什么?有人有这方面的经验吗?

【问题讨论】:

  • 你想做什么?添加stackoverflow.com/help/minimal-reproducible-example 让事情更清楚。
  • 如果没有GROUP BYOVER 子句,您将无法在SELECT 中执行COUNT;目前尚不清楚您在此处追求的是哪一个,并且没有样本数据或预期结果,我们无法给您明确的答案。
  • @nemo_87 先检查case语法,你有一个额外的case,应该是:case when t.EndDate
  • @jarlh 感谢您的回答,我将发布我的整个脚本,也许它会从那里更干净,也会添加详细的解释。谢谢建议
  • @ECris 谢谢,这解决了语法错误,我也会检查结果是否正确

标签: sql sql-server tsql


【解决方案1】:

您不能在update 中使用count(*)。这与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 表达式 无论如何都会返回 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

【讨论】:

  • 谢谢,例如它接近我需要的东西,我现在可以从中做出一些事情......仍然有一些不好的结果,但我想我需要更多的案例来涵盖这里@GordonLinoff
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-02
  • 2023-03-26
  • 2018-07-23
  • 1970-01-01
  • 2016-04-02
  • 1970-01-01
  • 2016-07-08
相关资源
最近更新 更多