2013-07-23 9 views
8

Guten Tag an alle. Ich möchte eine Frage zu meiner SQL-Anweisung stellen. Ich verwende SQL Server 2008 und hat eine Tabelle namens Workflow-Transaktion. In dieser Tabelle habe ich 12 Datensätze. Das Bild unten ist der Inhalt der Tabelle.UPDATE mit Unterabfragen - Updates mehr als die benötigten Datensätze

enter image description here

Ich habe diese SQL-Anweisung:

UPDATE Workflow_Txn 
SET Status = 1 
WHERE [RequestId] IN 
(
    SELECT [RequestId] 
    FROM Workflow_Txn 
    WHERE [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)  
    AND RequestId = 3 
) 

Mein Ziel ist es, eine Anforderungs-ID zu aktualisieren, die die Auftragsnummer von weniger als das Maximum, das die Ausgabe von der SELECT-Anweisung in seinem die WHERE-Klausel. Jetzt erwarte ich, dass die zu aktualisierenden Datensätze nur die besagten Datensätze sind (im Code ist es RequestId # 3).

Was tatsächlich passiert ist, wurde statt nur vier Datensätze aktualisiert, es wird fünf (5)! Gibt es ein Problem mit meiner bestehenden SQL-Anweisung?

Antwort

6

Ihr Problem besteht darin, dass Sie eine Aktualisierung aller Datensätze mit RequestId = 3 vornehmen. Berücksichtigen Sie, dass Ihr Unterabfrageergebnis 3 lautet, sodass Sie alle zugehörigen Datensätze aktualisieren.

Ihre Anfrage entspricht

UPDATE Workflow_Txn 
SET Status = 1 
WHERE RequestId = 3 

Nicht sicher zu tun, wenn Sie den Eindruck haben Ihre Abfrage komplexer zu machen, als es sein muss. Mir scheint, dass etwas einfacher würde den Trick

UPDATE Workflow_Txn 
SET Status = 1 
WHERE [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)  
     AND RequestId = 3 
+0

Ich denke, was Sie mir gezeigt haben, war einfacher als meins. Ich beabsichtige, die Datensätze zu aktualisieren, die niedriger als die Bestellnummer sind, d.h. ich würde die Datensätze vor dem letzten Datensatz aktualisieren. –

+0

@ Ju-chan: Soweit ich verstehe meine Abfrage sollte funktionieren, haben Sie es getestet? –

6

Das Problem mit Ihrer Anfrage ist, dass die Unterabfrage sehr ins Detail geht die Datensätze mit Auftragsnummer kleiner als das Maximum zu finden. Und dann wählt es alles mit der gleichen Anfrage - was die maximale Bestellnummer beinhalten würde.

Ich ziehe diese mit einem CTE wie folgt festzusetzen:

with toupdate as (
     select t.*, 
      MAX(OrderNumber) as MaxON 
     from Workflow_txn 
     where RequestId = 3 
    ) 
UPDATE toupdate 
    SET Status = 1 
    where OrderNumber < MaxON; 

Ich mag diese Struktur, weil ich den CTE separat ausgeführt werden können, um zu sehen, welche Datensätze wahrscheinlich aktualisiert werden.

Ihre Abfrage zu beheben, Sie würden die Anfrage OrderNumber zu verwenden ändern und wiederholen Sie den RequestId = 3:

UPDATE Workflow_Txn 
SET Status = 1 
WHERE [RequestId] = 3 and 
     OrderNumber in 
(
    SELECT [OrderNumber] 
    FROM Workflow_Txn 
    WHERE [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3)  
    AND RequestId = 3 
) 
+0

Ich mag den einfacheren Weg auch (obwohl ich meine erste Methode aus den in der Lösung angegebenen Gründen bevorzuge). Ich glaube jedoch, dass @StuartAinsworth zuerst mit der vereinfachten Version geantwortet hat - deshalb habe ich seine Antwort aufgewertet. –

4

Ihre subquery sagte nur RequestID von 3 zurück, so dass Sie alle Anforderungen mit dieser ID aktualisiert; Geh es durch. Was ich denke, Sie suchten nach etwas wie:

UPDATE Workflow_Txn 
SET Status = 1 
WHERE [RequestId] = 3 
AND [OrderNumber] < (SELECT MAX(OrderNumber) FROM Workflow_Txn WHERE RequestId = 3) 
Verwandte Themen