当newValue else previousValue时的sql情况

时间:2015-08-10 14:25:39

标签: sql sql-server select sql-update case

我正在尝试从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

3 个答案:

答案 0 :(得分:2)

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列中的升序选择先前的值。

答案 1 :(得分:1)

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; 应该做你想做的事。您可以将其直接放在class MyObject { value: number; unit: string; constructor(value: number, unit: string){ this.value = value; this.unit = unit; } } 定义中。或者使用子查询:

    <input id="myValue" type="number"></input>
    <input id="myUnit" type="text"></input>

答案 2 :(得分:1)

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

  

我们可以连续两行都有88个指示符吗? -   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
下面的

是用于更新具有最后一个值的表的示例小提琴 http://sqlfiddle.com/#!6/c78ae/8