sql case when newValue else previousValue

sql case when newValue else previousValue

我正在尝试从 Select 创建一个更新,其中在特定情况下 (88) 应该使用先前的值来更新列字段

UPDATE myTable
SET MyDateCol = CASE MYSelect.Indicator 
                WHEN 88 THEN @previosValue 
                ELSE MYSelect.NewValue
FROM  myTable
INNER JOIN    (    ...    ) AS MYSelect

ON myTable.ID = MYSelect.ID

示例:

MYSelect             | myTable
                     |
Indicator NewValue   | MyDateCol 
   0         1       |    1
   1         2       |    2
   88        3       |    2 <-
   3         4       |    4
   4         5       |    5
   5         6       |    6
   6         7       |    7
   88        8       |    7 <-

完整更新

UPDATE [dbo].[BestellDetails]
   SET [Datum] = CASE MYTABLE.WochenTag WHEN 88  THEN lag(MyDate) over(order by MYTABLE.MyDate)  ELSE MyDate END
FROM  [BestellDetails]
INNER JOIN
(
    SELECT INNERTabelle.BestellDetailId,INNERTabelle.WochenTag, DATEADD (dd,INNERTabelle.WochenTag, INNERTabelle.NewDatum) AS MyDate
    FROM
    (
        SELECT TOP 100 PERCENT BestellDetailId, 
                    dbo.FirstDateOfWeekISO8601(dbo.Bestellung.Jahr, 
                    dbo.Bestellung.Kalenderwoche) AS NewDatum,
                    (CASE BestellDetails.RefMenuId WHEN Speiseplandetails.RefMoId THEN 0 
                                                   WHEN Speiseplandetails.RefDiId THEN 1 
                                                   WHEN Speiseplandetails.RefMiId THEN 2 
                                                   WHEN Speiseplandetails.RefDoId THEN 3 
                                                   WHEN Speiseplandetails.RefFrId THEN 4 
                                                   WHEN Speiseplandetails.RefSaId THEN 5 
                                                   WHEN Speiseplandetails.RefSoId THEN 6 ELSE 88 END) AS WochenTag
        FROM            dbo.Speiseplandetails 
        RIGHT OUTER JOIN dbo.BestellDetails ON dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefMoId 
        OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefDiId 
        OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefMiId 
        OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefDoId 
        OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefFrId 
        OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefSaId 
        OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefSoId 

        RIGHT OUTER JOIN dbo.Bestellung ON dbo.BestellDetails.RefBestellId = dbo.Bestellung.BestellId

        order by BestellDetailId

    ) as INNERTabelle
) AS MYTABLE

ON [BestellDetails].BestellDetailId = MYTABLE.BestellDetailId
UPDATE myTable
SET MyDateCol = CASE MYSelect.Indicator 
                WHEN 88 THEN (select lag(newvalue) over(order by newvalue) from MySelect) -- @previosValue 
                ELSE MYSelect.NewValue
FROM  myTable
INNER JOIN    (    ...    ) AS MYSelect
ON myTable.ID = MYSelect.ID

这是假设必须根据 newvalue 列中的升序选择先前的值。

lag() 应该做你想做的。你可以直接把它放在 MySelect 定义中。或者使用子查询:

WITH myselect as (
      . . .
     )
UPDATE myTable
    SET MyDateCol = (CASE MYSelect.Indicator 
                        WHEN 88 THEN MYSelecct.prevvalue 
                        ELSE MYSelect.NewValue
                     END
FROM  myTable INNER JOIN
      (SELECT myselect.*, lag(newvalue) over (order by newvalue) as prevvalue
       FROM myselect
      ) myselect
      ON myTable.ID = MYSelect.ID;

请尝试以下查询。 它优化了您的查询,还处理了重复 88 值的情况。就我而言,我使用 NULL 而不是 88.

Can we have two rows in succession that both have an 88 indicator? – Damien_The_Unbeliever

CREATE TABLE #temp(
BestellDetailId int, row_num int,MyDate date
)

INSERT INTO #temp
SELECT TOP 100 PERCENT 
    BestellDetailId,
    ROW_NUMBER() OVER (order by BestellDetailId) as row_num,        
    (
    CASE BestellDetails.RefMenuId 
                               WHEN Speiseplandetails.RefMoId THEN DATEADD (dd,0, dbo.FirstDateOfWeekISO8601(dbo.Bestellung.Jahr, dbo.Bestellung.Kalenderwoche) )
                               WHEN Speiseplandetails.RefDiId THEN DATEADD (dd,1, dbo.FirstDateOfWeekISO8601(dbo.Bestellung.Jahr, dbo.Bestellung.Kalenderwoche) )
                               WHEN Speiseplandetails.RefMiId THEN DATEADD (dd,2, dbo.FirstDateOfWeekISO8601(dbo.Bestellung.Jahr, dbo.Bestellung.Kalenderwoche) )
                               WHEN Speiseplandetails.RefDoId THEN DATEADD (dd,3, dbo.FirstDateOfWeekISO8601(dbo.Bestellung.Jahr, dbo.Bestellung.Kalenderwoche) )
                               WHEN Speiseplandetails.RefFrId THEN DATEADD (dd,4, dbo.FirstDateOfWeekISO8601(dbo.Bestellung.Jahr, dbo.Bestellung.Kalenderwoche) )
                               WHEN Speiseplandetails.RefSaId THEN DATEADD (dd,5, dbo.FirstDateOfWeekISO8601(dbo.Bestellung.Jahr, dbo.Bestellung.Kalenderwoche) )
                               WHEN Speiseplandetails.RefSoId THEN DATEADD (dd,6, dbo.FirstDateOfWeekISO8601(dbo.Bestellung.Jahr, dbo.Bestellung.Kalenderwoche) )
                               ELSE NULL END
    ) AS MyDate

FROM  dbo.Speiseplandetails 
    RIGHT OUTER JOIN dbo.BestellDetails ON dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefMoId 
                OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefDiId 
                OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefMiId 
                OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefDoId 
                OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefFrId 
                OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefSaId 
                OR dbo.BestellDetails.RefMenuId = dbo.Speiseplandetails.RefSoId 
    RIGHT OUTER JOIN dbo.Bestellung ON dbo.BestellDetails.RefBestellId = dbo.Bestellung.BestellId
order by BestellDetailId

--updating the temp table with correct values
update t1
set t1.myDate=t3.myDate
from #temp t1 left join #temp t3 
on t3.row_num in 
(select max(row_num) from #temp t2 where t2.myDate is not null and t2.row_num<t1.row_num)
where t1.MyDate is NULL

UPDATE [dbo].[BestellDetails]
   SET [Datum] = MYTABLE.myDate
FROM  [BestellDetails]

INNER JOIN
#temp AS MYTABLE
ON [BestellDetails].BestellDetailId = MYTABLE.BestellDetailId

下面是使用最后一个值更新 table 的示例 fiddle http://sqlfiddle.com/#!6/c78ae/8