ฉันจะอัปเดต 100 อันดับแรกในเซิร์ฟเวอร์ sql ได้อย่างไร


393

ฉันต้องการอัปเดต 100 อันดับสูงสุดใน SQL Server ผมมีตารางT1ที่มีเขตข้อมูลและF1 มี 200 บันทึก ฉันต้องการอัปเดตฟิลด์ใน 100 รายการแรกสุด ฉันจะอัปเดตตามใน SQL Server ได้อย่างไรF2T1F1TOP 100

คำตอบ:


684

หมายเหตุจำเป็นต้องใช้วงเล็บในคำสั่ง UPDATE:

update top (100) table1 set field1 = 1

28
ความคิดวิธีการใช้order byเช่นกัน?
Joe Phillips

8
@JoePhilllips ใช้คำตอบ Martin Smith สำหรับการสั่งซื้อโดย
jjxtra

ไม่ใช่ระเบียน 100 อันดับแรก แต่เป็นเพียง 100 ระเบียนที่เลือกโดยพลการ 100 อันดับแรกจะรวมคำสั่งบางอย่างเพื่อจัดอันดับระเบียน
Thorsten Kettner

1
นี่เป็นการตอบคำถาม "ตามที่ถาม" แต่ TOP ไม่มีความหมาย (และคาดเดาไม่ได้) โดยไม่มีคำสั่งซื้อ ดูคำตอบเพิ่มเติมจาก Martin Smith
Andy G

1
btw: วงเล็บมีความสำคัญ!
Simon_Weaver

300

หากไม่มีORDER BYความคิดทั้งหมดที่ว่าTOPก็ไม่สมเหตุสมผลนัก คุณต้องมีคำจำกัดความที่สอดคล้องกันว่าทิศทางใด "ขึ้น" และ "ลง" สำหรับแนวคิดด้านบนที่จะมีความหมาย

อย่างไรก็ตาม SQL Server อนุญาต แต่ไม่รับประกันผลลัพธ์ที่กำหนดไว้

UPDATE TOPไวยากรณ์ในคำตอบที่ได้รับการยอมรับไม่สนับสนุนORDER BYข้อ แต่มันก็เป็นไปได้ที่จะได้รับหมายกำหนดที่นี่โดยใช้ CTE หรือตารางที่ได้รับการกำหนดลำดับการจัดเรียงที่ต้องการดังต่อไปนี้

;WITH CTE AS 
( 
SELECT TOP 100 * 
FROM T1 
ORDER BY F2 
) 
UPDATE CTE SET F1='foo'

71
คุณพูดไร้ความหมาย แต่นั่นไม่จริง ฉันยอมรับว่า / โดยปกติ / เมื่อคุณใช้TOPอัตราต่อรองคุณควรใช้กับORDER BYเพราะสิ่งที่คุณสนใจนั้นเป็นเหมือน "ที่สุด" หรือ "น้อยที่สุด" ของบางสิ่ง อย่างไรก็ตามในกรณีอื่น ๆ คุณอาจสนใจรับระเบียนที่ตรงกันเพียงรายการเดียวเท่านั้น เหมือนฉันวันนี้! ฉันต้องการแก้ไขปัญหาข้อมูล (รอบ) ทีละครั้ง กระบวนการแก้ไขทั้งหมดเกี่ยวข้องกับสคริปต์ db การแทรกแซงของผู้ใช้บางส่วนและการใช้งานบางอย่าง เราไม่ได้สนใจว่ามีการจัดการบันทึกใดก่อน เราแค่ใส่ใจว่าเราจัดการพวกมันทีละครั้ง
MetaFight

17
@MetaFight แต่ถ้าเป็นเช่นนั้นคุณจะมีWHEREประโยคที่จะไม่รวมการประมวลผลก่อนหน้านี้ คำถามตามคำตอบที่เขียนและยอมรับนั้นไม่มีความหมายเลย BTW: สำหรับการใช้ตารางเป็นคิวนี่เป็นลิงค์ที่มีประโยชน์
Martin Smith

10
ฉันต้องใช้งานโดยไม่ต้องมีคำสั่งเพื่อให้ฉันสามารถเรียกใช้กระบวนการอะซิงโครนัส ส่วนคำสั่ง where จะไม่รวมส่วนที่ประมวลผลแล้ว แต่ฉันสามารถประมวลผลได้ครั้งละมาก ๆ เท่านั้น ดังนั้นจึงมีกรณีการใช้ที่ถูกต้องสมบูรณ์
Jeff Davis

4
@Martin Smith: สมมติว่าคุณต้องการอัปเดตเป็นชุดพูดครั้งละ 10,000 ดูเหมือนจะเป็นการใช้งานที่ดีสำหรับสิ่งนี้และการสั่งซื้อก็ไม่สำคัญ สิ่งนี้ "ไม่สมเหตุสมผล" อย่างไร?
Jay Sullivan

5
@notfed นี่เป็นกรณีเดียวกับที่ได้พูดคุยกันถึงความตายในความคิดเห็นข้างต้น คำถามของคุณในกรณีนั้นจะไม่เหมือนคำตอบที่ยอมรับหรือไม่ คุณจะต้องมีwhereประโยคเพื่อหลีกเลี่ยงการประมวลผลแถวเดียวกันซ้ำแล้วซ้ำอีก
Martin Smith

14

สำหรับผู้ที่ชอบฉันยังคงติดอยู่กับ SQL Server 2000 SET ROWCOUNT {number};สามารถใช้ก่อนUPDATEแบบสอบถาม

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

จะ จำกัด การอัปเดตเป็น 100 แถว

มันถูกคัดค้านอย่างน้อยตั้งแต่ SQL 2005 แต่ ณ วันที่ SQL 2017 ยังคงใช้งานได้ https://docs.microsoft.com/en-us/sql/t-sql/statements/set-rowcount-transact-sql?view=sql-server-2017


1
SET ROWCOUNT ส่งผลกระทบต่อทริกเกอร์เช่นเดียวกับคำสั่งที่ถูกปรับปรุง หากคุณมีชุดลบแบบเรียงซ้อนมันสามารถทำธุรกรรมล้มเหลวได้หากมีจำนวนแถวเด็กแถวมากกว่าในตารางลูก
EricI

ด้วยที่กล่าวว่า SET ROWCOUNT @RowCountParameter; เป็นไวยากรณ์ที่ถูกต้องในขณะที่ SELECT TOP @RowCountParamter * FROM TableName ไม่ถูกต้อง หากคุณต้องการกำหนดค่าแถวที่กำลังอัปเดต SET ROWCOUNT # เป็นตัวเลือกที่ดีกว่าในขณะนี้หากคุณไม่ได้เปิดใช้งานตารางลูกที่มีการเปิดใช้งานการลบแบบเรียงซ้อน
EricI

ใน SQL Server 2017 เป็นไปได้ที่จะใช้ @variable ในประโยค TOP: docs.microsoft.com/en-us/sql/t-sql/queries/ ......
Alexandr Zarubkin


4

สิ่งที่น่าสนใจยิ่งกว่าคือความจริงที่ว่าคุณสามารถใช้ฟังก์ชั่น Table-Valued Function เพื่อเลือกแถว (และจำนวนที่จะผ่านTOP) เพื่ออัพเดต นั่นคือ:

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

สำหรับฟังก์ชั่นที่มีค่าของตารางคุณมีสิ่งที่น่าสนใจในการเลือกแถวที่ต้องการอัปเดต:

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
)

... และมีอยู่ (ในความเห็นต่ำต้อยของฉัน) พลังที่แท้จริงของการปรับปรุงแถวที่เลือกเท่านั้นด้านบนกำหนดขณะที่ในเวลาเดียวกันลดความซับซ้อนของไวยากรณ์ของUPDATEคำสั่ง



0

คุณสามารถอัปเดตจากการเลือกโดยใช้นามแฝงและเข้าร่วม:

UPDATE  TOP (500) T
SET     T.SomeColumn = 'Value'
FROM    SomeTable T
        INNER JOIN OtherTable O ON O.OtherTableFK = T.SomeTablePK
WHERE   T.SomeOtherColumn = 1
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.