2013-07-23 11 views
8

Buona giornata a tutti. Vorrei fare una domanda riguardo la mia dichiarazione SQL. Sto usando SQL Server 2008 e ho una tabella chiamata Workflow Transaction. In questa tabella, ho 12 record. L'immagine sotto è il contenuto della tabella.UPDATE utilizzando sottoquery - Aggiorna più dei record necessari

enter image description here

ho questa istruzione SQL:

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 
) 

Il mio obiettivo è quello di aggiornare un ID di richiesta che ha l'OrderNumber inferiore a quella massima, che sarà l'uscita dal SELECT all'interno la clausola WHERE. Ora mi aspetto che i record da aggiornare siano solo i detti record (nel codice, è RequestId # 3).

In realtà, invece di solo quattro record aggiornati, diventa cinque (5)! C'è un problema con la mia dichiarazione SQL esistente?

risposta

6

Il problema è che si sta eseguendo un aggiornamento di TUTTI i record con RequestId = 3. Tenere conto del fatto che il risultato della subquery è 3, quindi si finisce per aggiornare tutti i record correlati.

ricerca equivale a fare

UPDATE Workflow_Txn 
SET Status = 1 
WHERE RequestId = 3 

Non sono sicuro se si ha motivo per rendere la vostra query più complessa di quanto dovrebbe essere. Mi sembra che qualcosa di più semplice sarebbe fare il trucco

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

Penso che quello che mi hai mostrato fosse più semplice del mio. Sto mirando ad aggiornare i record inferiori al numero dell'ordine, cioè aggiornerei i record prima dell'ultimo record. –

+0

@ Ju-chan: Per quanto ho capito, la mia query dovrebbe funzionare, l'hai provato? –

6

Il problema con la query è che la sottoquery va in grande dettaglio per trovare i record con il numero d'ordine inferiore a quella massima. E poi sceglie tutto con la stessa richiesta - che includerebbe il numero massimo di ordini.

preferisco risolvere questo problema utilizzando un CTE come segue:

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

mi piace questa struttura, perché posso eseguire il CTE separatamente per vedere quali record sono suscettibili di essere aggiornato.

Per fissare la tua ricerca, è necessario modificare la richiesta di utilizzare OrderNumber e ripetere la 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

Mi piace anche il modo più semplice (anche se preferisco il mio primo metodo per i motivi indicati nella soluzione). Tuttavia, credo che @StuartAinsworth abbia risposto prima con la versione semplificata, motivo per cui ho svalutato la sua risposta. –

4

tuo subquery appena detto di tornare RequestID di 3, quindi aggiornati tutte le richieste con quel ID; cammina attraverso Quello che penso stavi cercando era qualcosa del tipo:

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