2009-08-11 5 views
335

Мне нужно проверить (из той же таблицы), если существует связь между двумя событиями на основе даты-времени.MySQL - запрос UPDATE на основе запроса SELECT

Один набор данных будет содержать конечную дату-время определенных событий, а другой набор данных будет содержать начальную дату-время для других событий.

Если первое событие завершено перед вторым событием, я хотел бы связать их.

То, что я до сих пор:

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 

Тогда я присоединиться к ним:

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 

Могу ли я тогда, основанный на моем validation_check поле, запустить UPDATE запрос с SELECT, вложенная?

+1

Я не уверен, что вы спрашиваете? Вы пытаетесь выяснить, как сделать обновление с помощью SQL Select? – RiddlerDev

ответ

573

Вы можете на самом деле сделать это один из двух способов:

обновление MySQL синтаксис объединения:

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 синтаксис:

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) 

Пика в зависимости от того, кажется наиболее естественным для вас.

+75

Первая форма (обновление с присоединением) будет * много более эффективной, чем вторая. Первый будет делать одно соединение, тогда как второе будет выполнять запрос выбора для каждой строки таблицыA. – ColinM

+12

Для первого примера, не следует ли использовать внутреннее соединение? Не приведет ли левое объединение к тому, что validation_check будет установлено значение null для записей tableA без соответствующей записи tableB? – Cerin

+3

@ Керин, что случилось со мной. Это должно быть внутреннее соединение! Или просто оставьте это как соединение. Если у вас нет внутреннего соединения, левое соединение означает, что все записи tableA будут обновлены! Это очень опасно! – CMCDragonkai

43

Если кто-то пытается обновить данные из одной базы данных в другую, независимо от того, на какую таблицу они нацелены, для этого должны быть некоторые критерии.

Это один лучше и чистым для всех уровней:

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! Он отлично работает!

С учетом вышеизложенного вы можете изменить установленные поля и критерии «on», чтобы выполнить свою работу. Вы также можете выполнить проверки, затем потянуть данные в таблицу temp, а затем запустить обновление, используя приведенный выше синтаксис, заменив имена таблиц и столбцов.

Надеюсь, что это сработает, если не дайте мне знать. Я напишу вам точный запрос.

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

Надеюсь, это сработает для вас.

+2

Это, безусловно, самый быстрый запрос. Редактировать: Имея dest с 22K строками и src с 4K строк, потребовалось менее 1 секунды, а верхний ответ - через 60 секунд. –

+1

Да, это самый быстрый запрос, BTW вы можете добавить предложение WHERE слишком – robinmag

+0

Хороший запрос. 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 ; 

Надеюсь, это поможет вам в случае, когда вам необходимо сопоставить и обновить между двумя таблицами.

9

Я нашел этот вопрос в поиске собственного решения для очень сложного соединения. Это альтернативное решение для более сложной версии проблемы, которая, как мне показалось, может быть полезна.

Мне нужно было заполнить поле product_id в таблице действий, где действия нумеруются в единице, а единицы нумеруются на уровне (идентифицированном с использованием строки N), чтобы можно было идентифицировать действия, используя SKU т.е. L1U1A1. Затем эти SKU хранятся в другой таблице.

Я определил следующий, чтобы получить список activity_id против 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) 

я обнаружил, что это было слишком сложно, чтобы включить в SELECT, в MySQL, так что я создал временную таблицу, и присоединился к этому с утверждением обновления: -

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; 

Я надеюсь, что кто-то считает это полезным

66

Легко в MySQL:

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

У меня есть знакомый вопрос, и мне интересно, могу ли я сделать что-то подобное с моей ситуацией: https://stackoverflow.com/questions/47948052/mysql-wordpress-records-update – MagicMiles

4

Вы можете обновить значения из другой таблицы с помощью внутреннего соединения, как этот

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]; 

Следуйте здесь, чтобы узнать, как использовать этот запрос http://www.voidtricks.com/mysql-inner-join-update/

или вы можете использовать выбрать в качестве подзапроса, чтобы сделать это

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

запрос объяснил подробно здесь 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

Вы можете использовать:

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

За одним столом,

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; 
Смежные вопросы