Wie kann ich die Top 100 Datensätze in SQL Server aktualisieren?

393

Ich möchte die Top 100 Datensätze in SQL Server aktualisieren. Ich habe eine Tabelle T1mit Feldern F1und F2. T1hat 200 Datensätze. Ich möchte das F1Feld in den Top 100 Datensätzen aktualisieren . Wie kann ich basierend auf TOP 100in SQL Server aktualisieren ?

Rajesh
quelle

Antworten:

684

Beachten Sie, dass die Klammern für UPDATE-Anweisungen erforderlich sind:

update top (100) table1 set field1 = 1
Umair Ahmed
quelle
28
Irgendeine Idee, wie man das order byauch benutzt?
Joe Phillips
8
@ JoePhilllips Verwenden Sie die Antwort von Martin Smith für die Bestellung bis
jjxtra
Dies sind jedoch nicht die Top 100 Datensätze, sondern einfach 100 willkürlich ausgewählte Datensätze. Zu den Top 100 gehört eine Reihenfolge, in der die Datensätze eingestuft werden.
Thorsten Kettner
1
Dies beantwortet die Frage "wie gestellt", aber TOP ist ohne BESTELLUNG bedeutungslos (und unvorhersehbar). Siehe die Antwort weiter unten von Martin Smith.
Andy G
1
Übrigens: Klammern sind wichtig!
Simon_Weaver
300

Ohne eine macht ORDER BYdie ganze Idee von TOPnicht viel Sinn. Sie müssen eine konsistente Definition haben, welche Richtung "oben" und welche "unten" ist, damit das Konzept von oben sinnvoll ist.

SQL Server erlaubt dies, garantiert jedoch kein deterministisches Ergebnis .

Die UPDATE TOPSyntax in der akzeptierten Antwort unterstützt keine ORDER BYKlausel, aber es ist möglich, hier eine deterministische Semantik zu erhalten, indem ein CTE oder eine abgeleitete Tabelle verwendet wird, um die gewünschte Sortierreihenfolge wie folgt zu definieren.

;WITH CTE AS 
( 
SELECT TOP 100 * 
FROM T1 
ORDER BY F2 
) 
UPDATE CTE SET F1='foo'
Martin Smith
quelle
71
Du sagst bedeutungslos, aber das stimmt nicht. Ich gebe zu, dass / normalerweise /, wenn Sie TOPGewinnchancen verwenden, Sie es verwenden sollten, ORDER BYweil das, woran Sie interessiert sind, das "Meiste" oder "Wenigste" von etwas ist. In anderen Fällen sind Sie möglicherweise nur an einem passenden Datensatz interessiert. Wie ich heute! Ich musste Datenprobleme (Zyklen) einzeln beheben. Der gesamte Fixierungsprozess umfasste ein DB-Skript, einige Benutzereingriffe und einige Anwendungsvorgänge. Es war uns egal, welcher Datensatz zuerst bearbeitet wurde. Wir haben uns nur darum gekümmert, dass wir sie einzeln behandeln.
MetaFight
17
@MetaFight Aber dann hätten Sie eine WHEREKlausel gehabt , um zuvor verarbeitete Datensätze auszuschließen. Die Frage als schriftliche und akzeptierte Antwort ist ziemlich bedeutungslos. Übrigens: Für die Verwendung von Tabellen als Warteschlange ist dies ein nützlicher Link
Martin Smith
10
Ich muss top ohne order by verwenden, damit ich einen asynchronen Prozess ausführen kann. Die where-Klausel enthält nicht diejenigen, die bereits verarbeitet wurden, aber ich kann nur so viele gleichzeitig verarbeiten. Es hat also einen vollkommen gültigen Anwendungsfall.
Jeff Davis
4
@ Martin Smith: Angenommen, Sie möchten stapelweise aktualisieren, z. B. 10000 gleichzeitig. Scheint eine gute Verwendung dafür zu sein, und die Reihenfolge spielt keine Rolle. Wie macht das "keinen Sinn"?
Jay Sullivan
5
@notfed Dies ist der gleiche Fall, der bereits in den obigen Kommentaren zu Tode diskutiert wurde. Ihre Anfrage würde in diesem Fall nicht so aussehen wie die in der akzeptierten Antwort, oder? Sie benötigen eine whereKlausel, um zu vermeiden, dass dieselben Zeilen immer wieder verarbeitet werden.
Martin Smith
14

für diejenigen wie mich, die immer noch mit SQL Server 2000 stecken, SET ROWCOUNT {number};kann vor der UPDATEAbfrage verwendet werden

SET ROWCOUNT 100;
UPDATE Table SET ..;
SET ROWCOUNT 0;

begrenzt das Update auf 100 Zeilen

Es ist mindestens seit SQL 2005 veraltet, aber ab SQL 2017 funktioniert es immer noch. https://docs.microsoft.com/en-us/sql/t-sql/statements/set-rowcount-transact-sql?view=sql-server-2017

Claudio B.
quelle
1
SET ROWCOUNT wirkt sich sowohl auf Trigger als auch auf den zu aktualisierenden Befehl aus. Wenn Sie die Kaskadenlöschmenge festgelegt haben, kann die Transaktion fehlschlagen, wenn mehr als die Anzahl der untergeordneten Zeilen in der untergeordneten Tabelle vorhanden ist.
EricI
Nachdem dies gesagt wurde, SET ROWCOUNT @RowCountParameter; ist eine gültige Syntax, während SELECT TOP @RowCountParamter * FROM TableName ungültig ist. Wenn Sie die zu aktualisierenden Zeilen konfigurieren müssen, ist SET ROWCOUNT # derzeit die bessere Option, vorausgesetzt, Sie haben keine untergeordneten Tabellen mit aktiviertem Kaskadenlöschen.
EricI
In SQL Server 2017 ist es jetzt möglich, @variable in der TOP-Klausel zu verwenden: docs.microsoft.com/en-us/sql/t-sql/queries/…
Alexandr Zarubkin
13
update tb set  f1=1 where id in (select top 100 id from tb where f1=0)
Hyyxing
quelle
4

Was noch cooler ist, ist die Tatsache, dass Sie eine Inline-Tabellenwertfunktion verwenden können, um auszuwählen, welche (und wie viele Via TOP) Zeilen aktualisiert werden sollen. Das ist:

UPDATE MyTable
SET Column1=@Value1
FROM tvfSelectLatestRowOfMyTableMatchingCriteria(@Param1,@Param2,@Param3)

Für die Tabellenwertfunktion haben Sie etwas Interessantes, um die zu aktualisierende Zeile auszuwählen, wie:

CREATE FUNCTION tvfSelectLatestRowOfMyTableMatchingCriteria
(
    @Param1 INT,
    @Param2 INT,
    @Param3 INT
)
RETURNS TABLE AS RETURN
(
    SELECT TOP(1) MyTable.*
    FROM MyTable
    JOIN MyOtherTable
      ON ...
    JOIN WhoKnowsWhatElse
      ON ...
    WHERE MyTable.SomeColumn=@Param1 AND ...
    ORDER BY MyTable.SomeDate DESC
)

... und da liegt (meiner bescheidenen Meinung nach) die wahre Kraft, nur die oben ausgewählten Zeilen deterministisch zu aktualisieren und gleichzeitig die Syntax der UPDATEAnweisung zu vereinfachen .

Michael Goldshteyn
quelle
0

Versuchen:

UPDATE Dispatch_Post
SET isSync = 1
WHERE ChallanNo 
IN (SELECT TOP 1000 ChallanNo FROM dbo.Dispatch_Post ORDER BY 
CreatedDate DESC)
Shahin Al Kabir Mitul
quelle
0

Sie können auch mithilfe von Alias ​​aktualisieren und beitreten und beitreten:

UPDATE  TOP (500) T
SET     T.SomeColumn = 'Value'
FROM    SomeTable T
        INNER JOIN OtherTable O ON O.OtherTableFK = T.SomeTablePK
WHERE   T.SomeOtherColumn = 1
Vanderlei Pires
quelle