2011-11-13 30 views
16

Tôi đang sử dụng SQL Server để hoán đổi hai giá trị trong hai hàng. Hãy để tôi cho thấy:Câu lệnh SQL UPDATE để chuyển đổi hai giá trị trong hai hàng

[ord] [name] 
1  John 
4  Jack 
7  Pete 
9  Steve 
11 Mary 

Này, tôi cần phải trao đổi [ord] số cho "Pete" và "Steve" để làm cho bảng này để được như vậy:

[ord] [name] 
1  John 
4  Jack 
9  Pete 
7  Steve 
11 Mary 

Điều này có vẻ giống như một tầm thường công việc nhưng tôi dường như không thể viết một câu lệnh SQL UPDATE cho nó.

Trả lời

19

Nếu 'Peter''Steve' là duy nhất trong bảng của bạn, điều này sẽ làm:

UPDATE TableX 
SET ord = (SELECT MIN(ord) + MAX(ord) 
      FROM TableX 
      WHERE name IN ('Peter', 'Steve') 
     ) - ord 
WHERE name IN ('Peter', 'Steve') 

hoặc (cải thiện bằng cách @Erwin):

UPDATE TableX 
SET ord = (SELECT SUM(ord) 
      FROM TableX 
      WHERE name IN ('Peter', 'Steve') 
     ) - ord 
WHERE name IN ('Peter', 'Steve') 
+0

Đã thay đổi quyết định một lần nữa. Tôi đã thử nghiệm và nó cũng hoạt động với MIN + MAX. –

+0

Điều tôi muốn viết để bắt đầu với: +1 để giải quyết vấn đề này với tổng hợp. Tôi cũng muốn làm điều đó, nhưng đã từ bỏ, bởi vì tôi không thể tìm thấy một tương đương với [array_agg()] (http://www.postgresql.org/docs/9.1/interactive/functions-aggregate.html) trong tSQL . –

+0

@ErwinBrandstetter: http://data.stackexchange.com/stackoverflow/q/117570/ –

4

Sử dụng một biểu thức CASE:

UPDATE yourtable 
SET [ord] = CASE [ord] WHEN 9 THEN 7 
         WHEN 7 THEN 9 END 
WHERE [ord] IN (7, 9) 
+1

Đây chỉ là một tập hợp con được đơn giản hóa của sự cố. Nó giả định rằng bạn truy vấn 'số thứ tự' của Pete và Steve trước tiên và tạo truy vấn với kết quả. –

+0

Vâng, rõ ràng là tôi không cố gắng mã hóa nó. Cảm ơn bạn đã cố gắng, mặc dù ... – ahmd0

+0

@ ahmd0: Xin lỗi, câu hỏi của bạn không rõ ràng. –

7

này rất giống với câu hỏi trước của bạn: SQL to move rows up or down in two-table arrangement
tôi đã chuẩn bị một demo on data.stackexchange.com cho bạn.

Chỉnh sửa: thiết lập được đơn giản hóa ngay bây giờ, vì vậy tôi đã đơn giản hóa truy vấn của mình cho phù hợp.

WITH x AS (SELECT name, ord FROM t WHERE name = 'Pete') -- must be unique! 
    , y AS (SELECT name, ord FROM t WHERE name = 'Steve') -- must be unique! 
UPDATE t 
SET ord = z.ord 
FROM (
    SELECT x.name, y.ord FROM x,y 
    UNION ALL 
    SELECT y.name, x.ord FROM x,y 
    ) z 
WHERE t.name = z.name; 

Truy vấn này chỉ cập nhật nếu cả hai hàng có thể được tìm thấy và không làm gì khác.

+1

Haha. Bạn biết đấy, tôi đã đăng câu hỏi này để thực sự hiểu rõ hơn về bài đăng khác của bạn.)) Bây giờ tôi biết những gì bạn có nghĩa là với mã đó. Cảm ơn một lần nữa. Thật không may lần này tôi sẽ đưa ra câu trả lời "" cho ypercube ở trên. Đó là một giải pháp rất gọn gàng với MAX/MAX hoặc SUM. – ahmd0

+0

@ ahmd0: Vâng, tôi đồng ý. Upvoted nó bản thân mình. :) tối thiểu/tối đa, btw., không tối đa/tối đa. Buồn cười, tôi đã có cùng một kết hợp ... –

+0

Rất tiếc. Tôi không thể chỉnh sửa ngay bây giờ ... – ahmd0

0
BEGIN TRANSACTION 

UPDATE TABLENAME 
SET ord = 9 
where name = 'Pete' 

UPDATE TABLENAME 
SET ord = 7 
where name = 'Steve' 

COMMIT TRANSACTION 
3
UPDATE Table_1 
SET ord = 
    CASE name 
    WHEN 'Pete' THEN (SELECT ord FROM Table_1 WHERE name = 'Steve') 
    WHEN 'Steve' THEN (SELECT ord FROM Table_1 WHERE name = 'Pete') 
    END 
WHERE name IN ('Pete', 'Steve') 

Bạn có thể dễ dàng thay thế 'Pete''Steve' với các tên khác ...

+0

Điều này sẽ làm việc trong ví dụ này. Cảm ơn. – ahmd0

Các vấn đề liên quan