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?

11.08.2009 20:39:40
Я не уверен, что вы спрашиваете? Вы пытаетесь выяснить, как сделать обновление с помощью SQL Select?
RiddlerDev 11.08.2009 20:49:36
11 ОТВЕТОВ
РЕШЕНИЕ

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

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

UPDATE tableA a
INNER JOIN tableB b ON a.name_a = b.name_b
SET validation_check = if(start_dts > end_dts, 'VALID', '')
-- where clause can go here

Синтаксис ANSI SQL:

UPDATE tableA SET validation_check = 
    (SELECT if(start_DTS > end_DTS, 'VALID', '') AS validation_check
        FROM tableA
        INNER JOIN tableB ON name_A = name_B
        WHERE id_A = tableA.id_A)

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

799
26.11.2018 00:51:40
Первая форма (обновление с объединением) будет намного более эффективной, чем вторая. Первый будет выполнять одиночное соединение, тогда как второй будет выполнять запрос на выборку для каждой строки таблицы A.
ColinM 8.11.2012 17:54:12
Для первого примера, вы не должны использовать внутреннее соединение? Не приведет ли левое соединение к тому, что validation_check будет установлен в null для записей tableA без соответствующей записи tableB?
Cerin 25.02.2014 17:14:15
@ Да, это случилось со мной. Это должно быть внутреннее соединение! Или просто оставьте это как join. Если у вас нет внутреннего соединения, левое соединение означает, что все записи таблицы А будут обновлены! Это очень опасно!
CMCDragonkai 14.05.2015 14:09:59
Спасибо за первое (у). Пока этому ответу более 7 лет. Я не могу поверить, почему никто не заявил, что второй не работает в некоторой базе данных, такой как MySQL. Вы получите эту ошибку:You can't specify target table ___ for update in FROM clause SQL.sql
Jugali Lakota 9.11.2016 16:20:50
Также обратите внимание, что до недавнего времени первый подход не работал с MySQL, когда tableA= tableB. Вы вынуждены создать временную таблицу для хранения промежуточного результата. (должен был написать аналогичный запрос для скрипта миграции)
svvac 21.09.2017 13:39:28

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

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

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

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

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

57
25.11.2018 16:29:27
UPDATE
    `table1` AS `dest`,
    (
        SELECT
            *
        FROM
            `table2`
        WHERE
            `id` = x
    ) AS `src`
SET
    `dest`.`col1` = `src`.`col1`
WHERE
    `dest`.`id` = x
;

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

297
20.07.2018 09:53:21
Это самый быстрый запрос. Изменить: Имея dest с 22K строк и SRC с 4K строк, это заняло менее 1 секунды, в то время как верхний ответ более 60 секунд.
Chris Dev 19.06.2017 15:06:55
Да, это самый быстрый запрос, кстати, вы также можете добавить предложение WHERE
robinmag 28.06.2017 18:19:24
Самое быстрое не всегда означает хорошее, это обновление не будет работать во всех случаях, на самом деле в некоторых случаях у вас будет непредвиденное поведение, все это - то, почему не ставить условие, и это не объединение
Emiliano 23.04.2019 23:05:55
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 ;

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

23
5.09.2018 09:46:27

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

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

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

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

12
31.10.2018 12:38:23
Два запроса могут не дать согласованного результата в многопоточной среде.
donald 25.03.2019 09:13:47

Легко в MySQL:

UPDATE users AS U1, users AS U2 
SET U1.name_one = U2.name_colX
WHERE U2.user_id = U1.user_id
113
6.07.2017 10:06:19

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

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/

4
15.10.2015 00:52:41
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];
7
21.11.2016 05:32:56

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

UPDATE Station AS st1, StationOld AS st2
   SET st1.already_used = 1
 WHERE st1.code = st2.code
4
3.03.2017 06:29:09

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

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;
3
1.12.2017 16:55:43

У меня была проблема с повторяющимися записями в одной таблице. Ниже подходы работали для меня. Это также было защищено @sibaz.

Наконец я решил это, используя следующие запросы:

  1. Запрос на выборку сохраняется во временной таблице

    IF OBJECT_ID(N'tempdb..#New_format_donor_temp', N'U') IS NOT NULL
        DROP TABLE #New_format_donor_temp;
    
    select *
    into #New_format_donor_temp
    from DONOR_EMPLOYMENTS
    where DONOR_ID IN (
      1, 2
    )
    
    -- Test New_format_donor_temp
    -- SELECT *
    -- FROM #New_format_donor_temp;
  2. Временная таблица объединяется в запросе на обновление.

    UPDATE de
    SET STATUS_CD=de_new.STATUS_CD, STATUS_REASON_CD=de_new.STATUS_REASON_CD, TYPE_CD=de_new.TYPE_CD
    FROM DONOR_EMPLOYMENTS AS de
      INNER JOIN #New_format_donor_temp AS de_new ON de_new.EMP_NO = de.EMP_NO
    WHERE
      de.DONOR_ID IN (
        3, 4
    )

Я не очень разбираюсь в SQL, пожалуйста, посоветуйте любой лучший подход, который вы знаете.

Выше запросы для сервера MySql.

1
11.05.2018 08:13:55