2 Stimmen

Wie aktualisiere ich die TOP 5 mit einer Unterauswahl?

Ich war überrascht zu sehen, dass die folgenden 34 Zeilen aktualisiert wurden...nicht 5:

UPDATE 
 Message
 SET StatusRawCode = 25
WHERE StatusRawCode in
  ( 
     Select TOP 5 
      M2.StatusRawCode
       From Message as M2
        Where M2.StatusRawCode = 5
  ) 

Irgendwelche Ideen, wie man das in die richtige Form bringen kann?

Ich danke Ihnen!

4voto

karlgrz Punkte 13885

Ich vermute, dass die StatusRawCode-Werte, die von Ihrer Unterabfrage zurückgegeben werden, Werte sind, die in den 34 Datensätzen verwendet werden, die aktualisiert wurden. Anstelle von

WHERE StatusRawCode IN

Verwenden Sie dies:

UPDATE 
    Message
SET StatusRawCode = 25
    WHERE PrimaryKey in
    ( 
        Select TOP 5 
            PrimaryKey
        From Message as M2
        Where M2.StatusRawCode = 5
    )

Im Wesentlichen werden Sie die Primärschlüssel der 5 Zeilen auswählen, die in der Unterabfrage aktualisiert werden sollen. Beachten Sie, dass dadurch nur die obersten 5 Datensätze auf der Grundlage der Cluster-Indexreihenfolge Ihrer Tabelle aktualisiert werden. Fügen Sie eine Order-By-Klausel hinzu, wenn Sie ein bestimmtes Kriterium für die TOP 5-Datensätze angeben möchten.

Wenn es zum Beispiel eine Spalte mit dem Namen Rang gibt, die Sie als Kriterium verwenden möchten, schreiben Sie Ihre Abfrage wie folgt:

UPDATE 
    Message
SET 
    StatusRawCode = 25
WHERE 
    PrimaryKey IN
    ( 
        SELECT TOP 5 
            PrimaryKey
        FROM 
            Message as M2
        WHERE 
            M2.StatusRawCode = 5
        ORDER BY
            Rank DESC
    )

So erhalten Sie die TOP 5 Datensätze basierend auf den Werten der Spalte Rang. Sie können Ihre Spalte nach Bedarf ersetzen.

2voto

shahkalpesh Punkte 32505

Gibt es eine Möglichkeit, die TOP 5 Zeilen eindeutig zu identifizieren?

Bei Ihrer Abfrage spielt es keine Rolle, ob Sie TOP 5 ausführen (da Sie Datensätze mit StatusRawCode = 5 auswählen). Ihre Abfrage ist also in gewisser Weise dasselbe wie

UPDATE 
 Message
 SET StatusRawCode = 25
WHERE StatusRawCode = 5

2voto

Eric Punkte 87889

Es scheint, dass StatusRawCode ist alles andere als einzigartig. Sie möchten den Primärschlüssel oder eine andere eindeutige Spalte zurückziehen, um die ersten fünf zu identifizieren. Sie aktualisieren jede Zeile, in der StatusRawCode ist gleich 5. Offenbar gibt es 34 Zeilen, die diese Bedingung erfüllen.

Außerdem, top 5 bedeutet nur etwas mit einem order by Klausel. SQL Server speichert die Zeilen nicht in einer bestimmten Reihenfolge, und es ist nicht garantiert, dass Sie jedes Mal die gleichen fünf Zeilen zurückbekommen. SQL Server speichert Zeilen in 8k-Seiten und garantiert keine konsistente Reihenfolge für Ihren Zeilensatz. Darauf können Sie sich nicht verlassen, und Sie muss einen order by um sicherzustellen, dass Sie die richtigen fünf Zeilen erhalten. Andernfalls aktualisieren Sie fünf zufällige Zeilen .

1voto

Remus Rusanu Punkte 280155

Sie müssen die IN-Bedingung auf einen eindeutigen Primärschlüssel anwenden.

In SQL 2K5 und später können Sie auch ein CTE verwenden:

  WITH cte AS (
     Select TOP 5 
      M2.StatusRawCode
       From Message as M2
        Where M2.StatusRawCode = 5
    ORDER BY ...
  )
  UPDATE cte 
  SET StatusRawCode = 25

0voto

Rob Farley Punkte 15180

Ich möchte mich anschließen und empfehlen, dass Sie eine UPDATE-Anweisung immer mit einer SELECT-Anweisung beginnen. Etwa so:

SELECT * 
--UPDATE m SET StatusRawCode = 25
FROM Message m
WHERE StatusRawCode in  (
        Select TOP 5
       M2.StatusRawCode
       From Message as M2
       Where M2.StatusRawCode = 5  
);

...aber passen Sie Ihre Anfrage auf jeden Fall an Ihre tatsächlichen Anforderungen an, sobald Sie sehen, was Sie falsch machen (was in diesem Fall wahrscheinlich ähnlich wie die Antwort von KG wäre)

Dies zeigt Ihnen die Zeilen an, die von Ihrer Abfrage betroffen sind... Wenn Sie dies richtig gemacht haben, ändern Sie die SELECT * für die UPDATE-Zeile (derzeit kommentiert), und Sie sollten vorhersehbare Ergebnisse erhalten.

Beachten Sie jedoch, dass UPDATE kein ORDER BY unterstützt. Wenn Sie also am Ende versuchen, UPDATE TOP (5)..., dann erhalten Sie nicht die gewünschten Ergebnisse.

Rob

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X