Использование COUNT (*) внутри оператора CASE в SQL Server - PullRequest
1 голос
/ 04 июня 2019

Можно ли использовать count (*) внутри оператора case в T-SQL? Я пытаюсь обновить записи в таблице, но мне бы хотелось иметь 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 Ответ

2 голосов
/ 04 июня 2019

Вы не можете использовать 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 в любом случае возвращает 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...