MySQL - запрос ОБНОВЛЕНИЯ, основанный на SELECT Query

308

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

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

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

Что я до сих пор:

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 вложенных?

  • 2
    Я не уверен, что вы спрашиваете? Вы пытаетесь выяснить, как сделать обновление с помощью SQL Select?
Теги:
select
sql-update

10 ответов

515
Лучший ответ

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

Синтаксис соединения обновления 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)

Выберите тот, который вам кажется наиболее естественным.

  • 81
    Первая форма (обновление с объединением) будет намного более эффективной, чем вторая. Первый будет выполнять одиночное соединение, тогда как второй будет выполнять запрос на выборку для каждой строки таблицы A.
  • 15
    Для первого примера, вы не должны использовать внутреннее соединение? Не приведет ли левое соединение к тому, что validation_check будет установлен в null для записей tableA без соответствующей записи tableB?
Показать ещё 6 комментариев
192
UPDATE table1 dest, (SELECT * FROM table2 where id=x) src 
  SET dest.col1 = src.col1 where dest.id=x ;

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

  • 4
    Это, безусловно, самый быстрый запрос. Изменить: Имея dest с 22K строк, и SRC с 4K строк, это заняло менее 1 секунды, в то время как верхний ответ более 60 секунд.
  • 1
    Да, это самый быстрый запрос, кстати, вы также можете добавить предложение WHERE
57

Легко в MySQL:

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

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

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

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, а затем запустить обновление, используя приведенный выше синтаксис, заменив имена таблиц и столбцов.

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

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 ;

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

8

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

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

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

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

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;

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

  • 0
    Два запроса могут не дать согласованного результата в многопоточной среде.
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/

или вы можете использовать select в качестве подзапроса для этого

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/

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

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

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

Для той же таблицы

UPDATE PHA_BILL_SEGMENT AS PHA,<br/>
     (SELECT BILL_ID, COUNT(REGISTRATION_NUMBER) AS REG <br/>
       FROM PHA_BILL_SEGMENT<br/>
        GROUP BY REGISTRATION_NUMBER, BILL_DATE, BILL_AMOUNT<br/>
        HAVING REG > 1) T<br/>
    SET PHA.BILL_DATE = PHA.BILL_DATE + 2<br/>
 WHERE PHA.BILL_ID = T.BILL_ID;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню