CẬP NHẬT SQL THIẾT LẬP một cột bằng một giá trị trong bảng liên quan được tham chiếu bởi một cột khác?


112

Tôi hy vọng điều đó có ý nghĩa, hãy để tôi giải thích:

Có một bảng dữ liệu theo dõi cho chương trình đố vui trong đó mỗi hàng có ..

QuestionID và AnswerID (có một bảng cho mỗi loại). Vì vậy, do một lỗi đã có một loạt các QuestionID được đặt thành NULL, nhưng QuestionID của một AnswerID có liên quan lại nằm trong bảng Câu trả lời.

Vì vậy, giả sử QuestionID là NULL và AnswerID là 500, nếu chúng ta đi đến bảng Câu trả lời và tìm thấy Câu trả lời 500, có một cột có QuestionID đáng lẽ ở đó giá trị NULL.

Vì vậy, về cơ bản tôi muốn đặt mỗi NULL QuestionID bằng với QuestionID được tìm thấy trong bảng Câu trả lời trên hàng Câu trả lời của AnswerID trong bảng theo dõi (cùng hàng với NULL QuestionID đang được viết).

Tôi sẽ làm điều này như thế nào?

UPDATE QuestionTrackings
SET QuestionID = (need some select query that will get the QuestionID from the AnswerID in this row)
WHERE QuestionID is NULL AND ... ?

Không chắc tôi sẽ làm cách nào để có thể gán QuestionID cho QuestionID từ AnswerID phù hợp ...


MySQL và Microsoft SQL Server đều hỗ trợ phần mở rộng cho cú pháp SQL để hỗ trợ UPDATE nhiều bảng. Các thương hiệu khác thì không. Bạn chưa cho biết thương hiệu cơ sở dữ liệu bạn đang sử dụng.
Bill Karwin

Câu trả lời:


171
update q
set q.QuestionID = a.QuestionID
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

Tôi khuyên bạn nên kiểm tra xem tập hợp kết quả cần cập nhật là gì trước khi chạy cập nhật (cùng một truy vấn, chỉ với một lựa chọn):

select *
from QuestionTrackings q
inner join QuestionAnswers a
on q.AnswerID = a.AnswerID
where q.QuestionID is null -- and other conditions you might want

Đặc biệt là mỗi id câu trả lời chắc chắn chỉ có 1 id câu hỏi liên quan.


7
Tôi không chắc tại sao nhưng điều này không hiệu quả với tôi, tuy nhiên điều này có hiệu quả: update QuestionTrackings q inner join QuestionAnswers a on q.AnswerID = a.AnswerID set q.QuestionID = a.QuestionID; dường như là cùng một truy vấn cơ bản theo một thứ tự khác. bất kỳ ý tưởng tại sao?
billynoah

2
@billynoah, ORA-00971: thiếu từ khóa SET trong Oracle
masT

2
Gặp sự cố với tình huống tương tự trong PhpMyAdmin trên MySQL. Trong trường hợp của tôi, cột nguồn và cột đích nằm trong cùng một bảng, nhưng lựa chọn bản ghi dựa trên bảng khác. Phiên bản "SELECT" của truy vấn hoạt động, nhưng câu lệnh UPDTATE gây ra lỗi cú pháp tại "FROM"
2NinerRomeo

3
Tôi đã vượt qua vấn đề của mình bằng cách loại bỏ "FROM" Nó trông giống như thế này:UPDATE table1 NATURAL JOIN table2 SET table1.col1 = table1.col2 WHERE table2.col3 ="condition"
2NinerRomeo

"q" từ "update q" trong câu trả lời có phải là tham số truy vấn theo nghĩa đen hay đó chỉ là cách viết tắt của bạn cho tên bảng?
Shawn

28

Nếu không có ký hiệu cập nhật và tham gia (không phải tất cả DBMS đều hỗ trợ điều đó), hãy sử dụng:

UPDATE QuestionTrackings
   SET QuestionID = (SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
   WHERE QuestionID IS NULL
     AND EXISTS(SELECT QuestionID
                        FROM AnswerTrackings
                        WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)

Thông thường trong một truy vấn như thế này, bạn cần xác định mệnh đề WHERE với mệnh đề EXISTS có chứa truy vấn phụ. Điều này ngăn không cho CẬP NHẬT thay đổi các hàng không có kết quả khớp (thường là vô hiệu hóa tất cả các giá trị). Trong trường hợp này, vì một ID câu hỏi bị thiếu sẽ thay đổi NULL thành NULL, điều đó được cho là không quan trọng.


Phương pháp này phù hợp với tôi trên Oracle 12c (trong đó phương thức cập nhật-tham gia không thành công).
shwartz

16

Tôi không biết liệu bạn có gặp phải vấn đề tương tự như tôi trên MySQL Workbench hay không nhưng chạy truy vấn với câu lệnh INNER JOINafter FROMkhông hoạt động với tôi. Tôi không thể chạy truy vấn vì chương trình phàn nàn về FROMcâu lệnh.

Vì vậy, để làm cho truy vấn hoạt động, tôi đã thay đổi nó thành

UPDATE table1 INNER JOIN table2 on table1.column1 = table2.column1
SET table1.column2 = table2.column4
WHERE table1.column3 = 'randomCondition';

thay vì

UPDATE a
FROM table1 a INNER JOIN table2 b on a.column1 = b.column1
SET a.column2 = b.column4
WHERE a.column3 = 'randomCondition';

Tôi đoán giải pháp của tôi là cú pháp phù hợp cho MySQL.


Vâng, có vẻ như đối với Mysql, JOIN được coi là một phần của phần 'table_references' của một truy vấn. Tham gia MySQL
AWP

12
UPDATE
    "QuestionTrackings"
SET
    "QuestionID" = (SELECT "QuestionID" FROM "Answers" WHERE "AnswerID"="QuestionTrackings"."AnswerID")
WHERE
    "QuestionID" is NULL
AND ...

1
Làm việc trên oracle cho tôi. Câu trả lời của @ eglasius không.
Lombas

7

Tôi đã có cùng một câu hỏi. Đây là một giải pháp làm việc tương tự như của eglasius. Tôi đang sử dụng postgresql.

UPDATE QuestionTrackings
SET QuestionID = a.QuestionID
FROM QuestionTrackings q, QuestionAnswers a
WHERE q.QuestionID IS NULL

Nó phàn nàn nếu q được sử dụng thay cho tên bảng ở dòng 1 và không có gì đứng trước QuestionID ở dòng 2.


3
 select p.post_title,m.meta_value sale_price ,n.meta_value   regular_price
    from  wp_postmeta m 
    inner join wp_postmeta n
      on m.post_id  = n.post_id
    inner join wp_posts p
      ON m.post_id=p.id 
    and m.meta_key = '_sale_price'
    and  n.meta_key = '_regular_price'
     AND p.post_type = 'product';



 update  wp_postmeta m 
inner join wp_postmeta n
  on m.post_id  = n.post_id
inner join wp_posts p
  ON m.post_id=p.id 
and m.meta_key = '_sale_price'
and  n.meta_key = '_regular_price'
 AND p.post_type = 'product'
 set m.meta_value = n.meta_value;

3

Đối với Mysql Bạn có thể sử dụng Truy vấn này

CẬP NHẬT table1 a, table2 b SET a.coloumn = b.coloumn WHERE a.id = b.id


1

Cập nhật dữ liệu bảng thứ 2 trong bảng thứ nhất cần phải tham gia bên trong trước khi SET:

`UPDATE `table1` INNER JOIN `table2` ON `table2`.`id`=`table1`.`id` SET `table1`.`name`=`table2`.`name`, `table1`.`template`=`table2`.`template`;

1

bên dưới hoạt động cho mysql

update table1 INNER JOIN table2 on table1.col1 =  table2.col1
set table1.col1 =  table2.col2

0

Tôi nghĩ rằng điều này sẽ làm việc.

UPDATE QuestionTrackings
SET QuestionID = (SELECT QuestionID
                  FROM AnswerTrackings
                  WHERE AnswerTrackings.AnswerID = QuestionTrackings.AnswerID)
WHERE QuestionID IS NULL
AND AnswerID IS NOT NULL;
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.