2009-08-11 71 views
335

Tôi cần kiểm tra (từ cùng một bảng) nếu có liên kết giữa hai sự kiện dựa trên ngày giờ.MySQL - UPDATE truy vấn dựa trên Truy vấn SELECT

Một tập hợp dữ liệu sẽ chứa ngày kết thúc của một số sự kiện nhất định và tập dữ liệu khác sẽ chứa ngày bắt đầu cho các sự kiện khác.

Nếu sự kiện đầu tiên hoàn thành trước sự kiện thứ hai thì tôi muốn liên kết chúng.

Những gì tôi có cho đến nay là:

SELECT name as name_A, date-time as end_DTS, id as id_A 
FROM tableA WHERE criteria = 1 


SELECT name as name_B, date-time as start_DTS, id as id_B 
FROM tableA WHERE criteria = 2 

Sau đó, tôi tham gia cùng họ:

SELECT name_A, name_B, id_A, id_B, 
if(start_DTS > end_DTS,'VALID','') as validation_check 
FROM tableA 
LEFT JOIN tableB ON name_A = name_B 

Tôi có thể sau đó, căn cứ vào lĩnh vực validation_check tôi, chạy một truy vấn UPDATE với lồng nhau CHỌN?

+1

Tôi không chắc chắn những gì bạn đang yêu cầu? Bạn đang cố gắng tìm ra cách để làm một bản cập nhật với một SQL Chọn? – RiddlerDev

Trả lời

573

Bạn thực sự có thể làm điều này một trong hai cách:

MySQL cập nhật tham gia cú pháp:

update tableA a 
left join tableB b on 
    a.name_a = b.name_b 
set 
    validation_check = if(start_dts > end_dts, 'VALID', '') 

ANSI SQL cú pháp:

update tableA set validation_check = 
    (SELECT if(start_DTS > end_DTS,'VALID','') as validation_check 
     FROM tableA 
     LEFT JOIN tableB ON name_A = name_B 
     WHERE id_A = tableA.id_A) 

Pick bất cứ ai có vẻ tự nhiên nhất cho bạn.

+75

Biểu mẫu đầu tiên (cập nhật với tham gia) sẽ trở thành * lô * hiệu quả hơn thứ hai. Đầu tiên sẽ thực hiện một phép nối đơn, trong khi lệnh thứ hai sẽ thực thi truy vấn chọn cho mỗi hàng của tableA. – ColinM

+12

Ví dụ đầu tiên, bạn có nên sử dụng kết nối bên trong không? Sẽ không kết quả bên trái tham gia trong validation_check được thiết lập để null cho bản ghi tableA mà không có một bản ghi tableB tương ứng? – Cerin

+3

@Câu chuyện yea đã xảy ra với tôi. Nó nên được tham gia bên trong! Hoặc chỉ để nó như là tham gia. Nếu bạn không có tham gia bên trong, phép nối bên trái có nghĩa là tất cả các bản ghi tableA sẽ được cập nhật! Điều này rất nguy hiểm! – CMCDragonkai

43

Nếu ai đó đang tìm cách cập nhật dữ liệu từ cơ sở dữ liệu này sang cơ sở dữ liệu khác, bất kể họ đang nhắm mục tiêu đến bảng nào thì phải có một số tiêu chí để thực hiện.

Đây là một tốt hơn và sạch cho tất cả các cấp:

update dbname1.content targetTable 

left join dbname2.someothertable sourceTable on 
    targetTable.compare_field= sourceTable.compare_field 
set 
    targetTable.col1 = sourceTable.cola 
    ,targetTable.col2 = sourceTable.colb 
    ,targetTable.col3 = sourceTable.colc 
    ,targetTable.col4 = sourceTable.cold 

Traaa! Nó hoạt động tuyệt vời!

Với sự hiểu biết trên, bạn có thể sửa đổi các trường tập và tiêu chí "bật" để thực hiện công việc của mình. Bạn cũng có thể thực hiện kiểm tra, sau đó kéo dữ liệu vào (các) bảng tạm thời và sau đó chạy bản cập nhật bằng cách sử dụng cú pháp trên thay thế tên bảng và cột của bạn.

Hy vọng nó hoạt động, nếu không cho tôi biết. Tôi sẽ viết một truy vấn chính xác cho bạn.

195
UPDATE table1 dest, (SELECT * FROM table2 where id=x) src 
    SET dest.col1 = src.col1 where dest.id=x ; 

Hy vọng công trình này phù hợp với bạn.

+2

Đây là truy vấn nhanh nhất. Chỉnh sửa: Có dest với 22K hàng, và src với 4K hàng, phải mất dưới 1 giây để hoàn thành, trong khi câu trả lời hàng đầu trên 60 giây. –

+1

Vâng, đây là truy vấn nhanh nhất, BTW bạn có thể thêm mệnh đề WHERE quá – robinmag

+0

Truy vấn hay. 5 Star – Zubair

9
UPDATE 
    receipt_invoices dest, 
    (SELECT 
    `receipt_id`, 
    CAST((net * 100)/112 AS DECIMAL (11, 2)) witoutvat 
    FROM 
    receipt 
    WHERE CAST((net * 100)/112 AS DECIMAL (11, 2)) != total 
    AND vat_percentage = 12) src 
SET 
    dest.price = src.witoutvat, 
    dest.amount = src.witoutvat 
WHERE col_tobefixed = 1 
    AND dest.`receipt_id` = src.receipt_id ; 

Hy vọng điều này sẽ giúp bạn trong trường hợp bạn phải khớp và cập nhật giữa hai bảng.

9

Tôi đã tìm thấy câu hỏi này trong việc tìm kiếm giải pháp của riêng mình cho một sự tham gia rất phức tạp. Đây là một giải pháp thay thế, cho một phiên bản phức tạp hơn của vấn đề, mà tôi nghĩ có thể hữu ích.

Tôi cần điền trường product_id vào bảng hoạt động, trong đó các hoạt động được đánh số trong đơn vị và đơn vị được đánh số ở mức (được xác định bằng chuỗi ?? N), sao cho có thể xác định hoạt động bằng SKU tức là L1U1A1. Các SKU đó sau đó được lưu trữ trong một bảng khác.

tôi xác định như sau để có được một danh sách các activity_id vs product_id: -

SELECT a.activity_id, w.product_id 
FROM activities a 
JOIN units USING(unit_id) 
JOIN product_types USING(product_type_id) 
JOIN web_products w 
    ON sku=CONCAT('L',SUBSTR(product_type_code,3), 'U',unit_index, 'A',activity_index) 

tôi thấy rằng đó là quá phức tạp để kết hợp vào một SELECT trong mysql, vì vậy tôi đã tạo ra một bảng tạm thời, và tham gia mà với báo cáo cập nhật: -

CREATE TEMPORARY TABLE activity_product_ids AS (<the above select statement>); 

UPDATE activities a JOIN activity_product_ids b ON a.activity_id=b.activity_id 
    SET a.product_id=b.product_id; 

tôi hy vọng ai đó tìm thấy này hữu ích

66

dễ dàng trong MySQL:

UPDATE users AS U1, users AS U2 
SET U1.name_one = U2.name_colX 
WHERE U2.user_id = U1.user_id 
+0

Tôi có một câu hỏi tương tự, và tôi tự hỏi nếu tôi có thể làm điều gì đó tương tự với tình hình của tôi: https://stackoverflow.com/questions/47948052/mysql-wordpress-records-update – MagicMiles

4

Bạn có thể cập nhật các giá trị từ bảng khác sử dụng bên tham gia như thế này

UPDATE [table1_name] AS t1 INNER JOIN [table2_name] AS t2 ON t1.column1_name] = t2.[column1_name] SET t1.[column2_name] = t2.column2_name]; 

theo đây để biết cách sử dụng truy vấn này http://www.voidtricks.com/mysql-inner-join-update/

hoặc bạn có thể sử dụng lựa chọn như subquery để làm

này
UPDATE [table_name] SET [column_name] = (SELECT [column_name] FROM [table_name] WHERE [column_name] = [value]) WHERE [column_name] = [value]; 

truy vấn được giải thích chi tiết tại đây http://www.voidtricks.com/mysql-update-from-select/

4
UPDATE [table_name] AS T1, 
     (SELECT [column_name] 
     FROM [table_name] 
     WHERE [column_name] = [value]) AS T2 
    SET T1.[column_name]=T2.[column_name] + 1 
WHERE T1.[column_name] = [value]; 
2

Bạn có thể sử dụng:

UPDATE Station AS st1, StationOld AS st2 
    SET st1.already_used = 1 
WHERE st1.code = st2.code 
0

Đối với cùng một bảng,

UPDATE PHA_BILL_SEGMENT AS PHA, 
    (SELECT BILL_ID, COUNT(REGISTRATION_NUMBER) AS REG 
     FROM PHA_BILL_SEGMENT 
     GROUP BY REGISTRATION_NUMBER, BILL_DATE, BILL_AMOUNT 
     HAVING REG > 1) T 
    SET PHA.BILL_DATE = PHA.BILL_DATE + 2 
WHERE PHA.BILL_ID = T.BILL_ID; 
Các vấn đề liên quan