2017-10-31 1 views
0

Ich habe eine claimstable wie folgt.Innere Verknüpfung in Select-Anweisung zum Erstellen einer Variablen in SQL Server

Time    Terminal_ID Claims Count 
------------------------------------------- 
2017-10-19 06:03:00  1  451  1 
2017-10-19 06:04:00  1  452  2 
2017-10-19 06:05:00  1  452.3  2 
2017-10-19 06:06:00  1  458  2 
2017-10-19 06:03:00  9  459  6 
2017-10-19 06:04:00  9  461.2  5 
2017-10-19 06:05:00  9  462  2 
2017-10-19 06:06:00  9  463  1 

ich wählen time, claim und eine neue Spalte Claims_Change aus meiner Tabelle erstellen. Danach füge ich es in eine temporäre Tabelle ein.

Meine erwartete Ausgabe wäre:

  Time  Terminal_ID Claims Count Claims_change 
    --------------------------------------------------------- 
    2017-10-19 06:03:00  1  451  1  Null 
    2017-10-19 06:04:00  1  452  2  1 
    2017-10-19 06:05:00  1  452.3  2  0.3 
    2017-10-19 06:06:00  1  458  2  5.7 
    2017-10-19 06:03:00  9  459  6  Null 
    2017-10-19 06:04:00  9  461.2  5  2.2 
    2017-10-19 06:05:00  9  462  2  0.8 
    2017-10-19 06:06:00  9  463  1  1 

Dies ist meine Frage:

select 
    [Time], Terminal_ID, Claims, 
    convert(decimal(12, 3), y.[Claims] - (select t1.[Claims] 
              from claimstable t1 
              where t1.Terminal_ID = y.Terminal_ID 
              and t1.[Time] = (select max([Time]) 
                  from claimstable t2 
                  where t2.Terminal_ID = t1.Terminal_ID 
                   and t2.[Time] < y.[Time]) 
        )) as Claims_change 
into 
    #temptable 
from 
    claimstable as y 

Als ich dies für 5000 Zeilen getestet, es funktioniert gut, aber wenn ich diese Prüfung mit 100.000 Zeilen ich erhalte eine Fehlermeldung wie diese,

Msg 512, Ebene 16, Status 1, Zeile 42
Subqu er gab mehr als 1 Wert zurück. Dies ist nicht zulässig, wenn die Unterabfrage folgt =,! =, <, < =,>,> = oder wenn die Unterabfrage als Ausdruck verwendet wird.

ich las war etwas älter posts, die empfohlene Antwort inner join zu verwenden.

Auch in meinem Fall kann ich nicht genau schreiben, um Claims_change Variable mit inner join zu erhalten.

Jede Hilfe wäre genial.

+0

können Sie auch die erwartete Ausgabe anzeigen? –

+2

Sie versuchen, eine Ergebnismenge von einer Zahl zu subtrahieren. Wenn dieses Resultset mehr als einen Wert zurückgibt, weiß SQL Server nicht, was Sie eigentlich tun sollen. Zum Beispiel, was ist 3 - (1, 4, 6)? Wenn Sie mehrere Zeilen zurückgeben möchten, müssen Sie Ihrer Frage zusätzliche Informationen hinzufügen, die Ihre genauen Anforderungen angeben. Wenn nicht, dann müssen Sie herausfinden, warum Sie mehrere Zeilen erhalten und was die Geschäftsregeln sind, um das auf eine Zeile zu reduzieren. –

+0

@TomH, du hast Recht, nach deinem Kommentar habe ich ein wenig in die Daten gegraben und festgestellt, dass ich irgendwie einen doppelten Eintrag hatte. Ich fand es und reparierte es, danke für den tollen Kommentar :) –

Antwort

1

Sie können dies versuchen.

select 
    [Time], Terminal_ID, y.Claims, convert(decimal(12,3), y.[Claims]- t2.[Claims]) as Claims_change 
into 
    #temptable 
from 
    claimstable as y 
    OUTER APPLY (SELECT TOP 1 t1.[Claims] FROM claimstable t1 where 
      t1.Terminal_ID = y.Terminal_ID AND y.[Time] > t1.[Time] ORDER BY [Time] DESC) as t2 

Ergebnis:

Time     Terminal_ID Claims  Claims_change 
----------------------- ----------- ------------ --------------- 
2017-10-19 06:03:00.000 1   451.00  NULL 
2017-10-19 06:04:00.000 1   452.00  1.000 
2017-10-19 06:05:00.000 1   452.30  0.300 
2017-10-19 06:06:00.000 1   458.00  5.700 
2017-10-19 06:03:00.000 9   459.00  NULL 
2017-10-19 06:04:00.000 9   461.20  2.200 
2017-10-19 06:05:00.000 9   462.00  0.800 
2017-10-19 06:06:00.000 9   463.00  1.000 
+0

danke für die Mühe, ich werde das versuchen, und ich bin neu in 'OUTER APPLY'. Ich werde versuchen, mehr darüber zu lesen! Wie Tom H bereits in den Kommentaren erwähnt hat, hatte er recht, denke ich. Ich hatte einen doppelten Datensatz, der die Abfrage fehlgeschlagen hat. –

1

Wenn die Version von SQL Server Sie auf den Ständern sind LAG verwenden

select t.*,t.claims-lag(t.claims) over(partition by terminal_id order by time) as claims_change 
from claimstable t 

LAG den Wert einer bestimmten Spalte von der vorherigen Reihe wird basierend auf eine bestimmte Reihenfolge und Partitionierung. LAG für die erste Zeile (in einer Partition) wird NULL sein. Sie können das optionale Argument verwenden, um einen Standardwert anzugeben.

+0

Mir ist LAG nicht bekannt. Ich verwende Sql Server 2016 und werde dafür sorgen, dass ich darüber lese! –

Verwandte Themen