2017-03-21 1 views
1

ich eine Tabelle wie folgt in #def haben:Aktualisierung mit Quer anwenden

#def table ich die Anzahl der Tage zwischen den einzelnen Serviceauftrag für die laufende Periode ‚201702‘ nur berechnet werden soll. Reservation = 0 bedeutet, dass es vorher nicht gewartet wurde. Die Anzahl der Reservierungen erhöht sich mit jeder Reservierung.

select 
s1.period, 
,s1.company 
,s1.prod 
,s1.id1 
,S1.id2 
,s1.serv_date 
,t.last_servdate 
,datediff(dd, ISNULL(T.last_servdate, s1.[serv_Date]),s1.serv_date)AS [Days  Since last] from #def s1 
Outer apply(
select 
top 1 serv_date as last_servdate from #def s2 
where s1.prod=s2.prod and s1.id1 =s2.id1 
and s1.id2=s2.id2 and s1.company =s2.company 
and s2.reservice = s1.reservice-1 and s1.company =’abc’ 
and s2.company =’abc’)T 
where s1.company_code =’abc’ and s1.period ='201702' 

    update s1 
    set days_btwn_service = datediff(dd, ISNULL(T.last_servdate,s1.serv_Date]),s1.serv_date) from #def s1 
    Outer apply(
    select top 1 serv_date as last_servdate from #def s2 
    where s1.prod=s2.prod 
    and s1.id1 =s2.id1 
    and s1.id2=s2.id2 
    and s1.company =s2.company 
    and s2.reservice = s1.reservice-1 
    and s1.company =’abc’ 
    and s2.company =’abc’ 
)T where s1.company_code =’abc’ and s1.period ='201702' 

Die Auswahl Abfrage oben gibt mir das gewünschte Ergebnis. Seltsamerweise verwendet die UPDATE-Anweisung mit derselben Abfrage nicht das gewünschte Ergebnis, aber nur sehr wenige Zeilen werden mit Werten aktualisiert. Ich habe keine Idee warum?!

def enthält eine Liste aller Bestellungen, die mehr als einmal bestellt wurden.

Edit: Basierend auf @sqlzim Antwort habe ich die Abfrage geändert. Seine Antwort gibt die gleiche Antwort.

+0

Linksbündig SQL ... So schwer zu lesen ... – jarlh

+0

Bitte fügen Sie einige Beispieltabellendaten und das erwartete Ergebnis - auch im formatierten Text. Zeigen Sie uns auch Ihren aktuellen Abfrageversuch – TheGameiswar

Antwort

2

Dies sieht aus wie SQL-Server, also ist diese Antwort für SQL-Server.

Ich sehe nicht, warum Sie zwei unterschiedliche Ergebnisse aus diesen Anfragen bekommen würde, aber wenn Sie das richtige Ergebnis mit Ihrer select Anweisung bekommen, können Sie es in einem common table expression und update die cte mit setzen könnte.

Ist serv_date nullfähig? Wenn nicht, kann T.serv_date nicht null sein, es sei denn, Sie verwenden outer apply() anstelle von cross apply().

;with cte as (
select 
    s1.ord_id 
    , s1.period 
    , s1.company 
    , s1.prod 
    , s1.id1 
    , S1.id2 
    , s1.serv_date 
    , s1.days_btwn_service 
    , t.last_servdate 
    , datediff(day,isnull(T.last_servdate,s1.[serv_Date]),s1.serv_date) as [Days_Since_Last] 
from #def s1 
    cross apply ( 
    select top 1 serv_date as last_servdate 
    from #def s2 
    where s1.prod = s2.prod 
     and s1.id1 = s2.id1 
     and s1.id2 = s2.id2 
     and s1.company = s2.company 
     and s2.reservice = s1.reservice - 1 
    ) T 
where s1.company_code = 'abc' 
and s1.period = '201702' 
) 
--select * from cte; 
update cte 
    set days_btwn_service = [Days_Since_Last]; 
    /* This will update the underlying table #def */ 

/* -- Alternate version 
update d 
    set d.days_btwn_service = cte.[Days_Since_Last] 
    from #def d join cte on cte.ord_id=d.ord_id 
--*/ 

Überprüfen Sie die Ergebnisse der select, wenn sie richtig sind, führen Sie den update anstelle des select.

+0

Sooo viel einfacher zu lesen als die gepostete Frage –

+0

@JohnCappelletti Meistens von 'T-Sql Formatter' des Armen Mannes im Notizblock ++ – SqlZim

+0

Ah. Nun, Sie wissen, "Real Men" Code in Notepad –