bagaimana saya dapat memperbarui 100 catatan teratas di server sql

393

Saya ingin memperbarui 100 catatan teratas di SQL Server. Saya punya tabel T1dengan bidang F1dan F2. T1memiliki 200 catatan. Saya ingin memperbarui F1bidang dalam 100 catatan teratas. Bagaimana saya bisa memperbarui berdasarkan pada TOP 100SQL Server?

Rajesh
sumber

Jawaban:

684

Catatan, tanda kurung diperlukan untuk pernyataan UPDATE:

update top (100) table1 set field1 = 1
Umair Ahmed
sumber
28
Adakah yang tahu bagaimana cara menggunakannya order by?
Joe Phillips
8
@JoePhilllips Gunakan jawaban Martin Smith untuk pesanan oleh
jjxtra
Namun, ini bukan 100 catatan teratas, tetapi hanya 100 catatan yang dipilih secara sewenang-wenang. Top 100 akan mencakup beberapa urutan untuk memeringkat catatan.
Thorsten Kettner
1
Ini menjawab pertanyaan "seperti yang diminta" tetapi TOP tidak ada artinya (dan tidak dapat diprediksi) tanpa beberapa PESANAN. Lihat jawabannya lebih jauh ke bawah oleh Martin Smith.
Andy G
1
btw: kurung itu penting!
Simon_Weaver
300

Tanpa ORDER BYseluruh ide TOPtidak masuk akal. Anda harus memiliki definisi yang konsisten tentang arah mana yang "naik" dan yang "turun" agar konsep top menjadi bermakna.

Meskipun demikian SQL Server memperbolehkannya tetapi tidak menjamin hasil yang deterministik .

The UPDATE TOPsintaks dalam jawaban yang diterima tidak mendukung ORDER BYklausa namun ada kemungkinan untuk mendapatkan semantik deterministik sini dengan menggunakan CTE atau meja diturunkan untuk menentukan urutan yang diinginkan seperti di bawah ini.

;WITH CTE AS 
( 
SELECT TOP 100 * 
FROM T1 
ORDER BY F2 
) 
UPDATE CTE SET F1='foo'
Martin Smith
sumber
71
Anda mengatakan tidak berarti tetapi itu tidak benar. Saya akui bahwa, / biasanya /, ketika Anda menggunakan TOPpeluang, Anda harus menggunakannya dengan ORDER BYapa yang Anda minati adalah seperti "paling" atau "paling tidak" dari sesuatu. Namun, dalam kasus lain, Anda mungkin hanya tertarik untuk mendapatkan satu catatan yang cocok. Sukai saya hari ini! Saya perlu memperbaiki masalah data (siklus) satu per satu. Seluruh proses perbaikan melibatkan skrip db, beberapa intervensi pengguna, dan beberapa operasi aplikasi. Kami tidak peduli catatan WHICH yang ditangani terlebih dahulu. Kami hanya peduli bahwa kami menangani mereka satu per satu.
MetaFight
17
@MetaFight Tapi kemudian Anda akan memiliki WHEREklausa untuk mengecualikan catatan yang sebelumnya diproses. Pertanyaan sebagai jawaban tertulis dan diterima sangat tidak berarti. BTW: Untuk menggunakan tabel sebagai antrian, ini adalah tautan yang cukup berguna
Martin Smith
10
Saya perlu menggunakan top tanpa memesan sehingga saya dapat menjalankan proses asinkron. Klausa mana tidak akan menyertakan klausa yang sudah diproses, tapi saya hanya bisa memproses begitu banyak dalam satu waktu. Jadi ini memiliki kasus penggunaan yang valid sempurna.
Jeff Davis
4
@ Martin Smith: Katakanlah Anda ingin memperbarui dalam batch, katakan 10.000 sekaligus. Sepertinya digunakan untuk hal ini, dan pesanan tidak masalah. Bagaimana ini "tidak masuk akal"?
Jay Sullivan
5
@notfed Ini adalah kasus yang sama dengan yang telah dibahas sampai mati dalam komentar di atas. Permintaan Anda dalam hal itu tidak akan terlihat seperti yang ada di jawaban yang diterima kan? Anda membutuhkan whereklausa untuk menghindari pemrosesan baris yang sama berulang kali.
Martin Smith
14

bagi yang seperti saya masih terjebak dengan SQL Server 2000, SET ROWCOUNT {number};dapat digunakan sebelum UPDATEpermintaan

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

akan membatasi pembaruan hingga 100 baris

Sudah ditinggalkan setidaknya sejak SQL 2005, tetapi pada SQL 2017 masih berfungsi. https://docs.microsoft.com/en-us/sql/t-sql/statements/set-rowcount-transact-sql?view=sql-server-2017

Claudio B
sumber
1
SET ROWCOUNT memengaruhi pemicu serta perintah yang diperbarui. Jika Anda memiliki set penghapusan kaskade, itu bisa gagal transaksi jika lebih dari jumlah baris baris anak ada di tabel anak.
EricI
Dengan itu, SET ROWCOUNT @RowCountParameter; sintaks yang valid, sedangkan SELECT TOP @RowCountParamter * FROM TableName tidak valid. Jika Anda perlu mengkonfigurasi baris yang sedang diperbarui, SET ROWCOUNT # saat ini merupakan pilihan yang lebih baik, asalkan Anda tidak memiliki tabel anak dengan penghapusan kaskade diaktifkan.
EricI
Dalam SQL Server 2017 sekarang dimungkinkan untuk menggunakan @variable dalam klausa TOP: 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
sumber
4

Yang lebih keren adalah kenyataan bahwa Anda dapat menggunakan Fungsi Table-Valued inline untuk memilih TOPbaris ( dan berapa banyak ) yang akan diperbarui. Itu adalah:

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

Untuk fungsi bernilai tabel, Anda memiliki sesuatu yang menarik untuk memilih baris yang akan diperbarui seperti:

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
)

..., dan ada kebohongan (menurut pendapat saya yang sederhana) kekuatan sebenarnya dari memperbarui hanya baris yang dipilih paling deterministik sementara pada saat yang sama menyederhanakan sintaks UPDATEpernyataan.

Michael Goldshteyn
sumber
0

Mencoba:

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
sumber
0

Anda juga dapat memperbarui dari pilih menggunakan alias dan bergabung:

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
sumber