MySQL - 基于SELECT Query的UPDATE查询

Joh*_*n M 465 mysql select sql-update

我需要检查(从同一个表)基于日期时间的两个事件之间是否存在关联.

一组数据将包含某些事件的结束日期时间,另一组数据将包含其他事件的开始日期时间.

如果第一个事件在第二个事件之前完成,那么我想将它们链接起来.

到目前为止我所拥有的是:

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
Run Code Online (Sandbox Code Playgroud)

然后我加入他们:

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
Run Code Online (Sandbox Code Playgroud)

那么,基于我的validation_check字段,我可以使用SELECT嵌套运行UPDATE查询吗?

Eri*_*ric 763

您实际上可以通过以下两种方式之一来实现:

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
Run Code Online (Sandbox Code Playgroud)

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)
Run Code Online (Sandbox Code Playgroud)

挑选一个对你来说最自然的东西.

  • 第一种形式(使用连接更新)将比第二种形式更有效*.第一个将执行单个连接,而第二个将执行tableA的每一行的select查询. (87认同)
  • 对于第一个示例,您不应该使用内连接吗?对于没有相应tableB记录的tableA记录,左连接是否会导致validation_check被设置为null? (16认同)
  • 谢谢你的第一个(y).虽然这个答案超过7年.我无法相信为什么没有人说过第二个在MySQL等数据库中不起作用.您将收到此错误:`您无法在FROM子句SQL.sql中为更新指定目标表___ (7认同)
  • @Cerin是的,发生在我身上.它应该是内部联接!或者只是将其作为联接.如果您没有内连接,则左连接意味着将更新所有tableA记录!这非常危险! (3认同)
  • 另请注意,直到最近,当“tableA”=“tableB”时,第一种方法还无法在 MySQL 上运行。您被迫创建一个临时表来存储中间结果。(必须为迁移脚本编写类似的查询) (2认同)

小智 280

UPDATE
    `table1` AS `dest`,
    (
        SELECT
            *
        FROM
            `table2`
        WHERE
            `id` = x
    ) AS `src`
SET
    `dest`.`col1` = `src`.`col1`
WHERE
    `dest`.`id` = x
;
Run Code Online (Sandbox Code Playgroud)

希望这对你有用.

  • 这是迄今为止最快的查询.编辑:拥有22K行的dest和具有4K行的src,完成时间不到1秒,而最高答案超过60秒. (4认同)
  • 最快并不总是意味着好,此更新不适用于所有情况,实际上在某些情况下您会出现意外行为,这就是为什么不放置条件而不是加入的原因 (2认同)

Ser*_*gio 107

在MySQL中很容易:

UPDATE users AS U1, users AS U2 
SET U1.name_one = U2.name_colX
WHERE U2.user_id = U1.user_id
Run Code Online (Sandbox Code Playgroud)

  • 从另一张表简单更新一个列的最佳答案 (5认同)

KMX*_*KMX 56

如果有人正在寻求将数据从一个数据库更新到另一个数据库而不管他们所针对哪个表,那么必须有一些标准来实现它.

对于所有级别,这个更好,更干净:

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 
Run Code Online (Sandbox Code Playgroud)

Traaa!它很棒!

通过上述理解,您可以修改设置字段和"开启"条件来完成您的工作.您还可以执行检查,然后将数据拉入临时表,然后使用上述语法替换表名和列名来运行更新.

希望它有效,如果不让我知道.我会为你写一个确切的查询.


Don*_*Don 17

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 ;
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助您在两个表之间进行匹配和更新的情况.


sib*_*baz 12

我在寻找一个非常复杂的连接的自己的解决方案时发现了这个问题.这是一个替代解决方案,对于更复杂的问题版本,我认为这可能是有用的.

我需要填充活动表中的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)
Run Code Online (Sandbox Code Playgroud)

我发现这太复杂了,无法在mysql中加入SELECT,所以我创建了一个临时表,并将其与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;
Run Code Online (Sandbox Code Playgroud)

我希望有人觉得这很有用


bha*_*vik 7

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];
Run Code Online (Sandbox Code Playgroud)


Ana*_*han 5

您可以像这样使用内部联接更新另一个表中的值

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];
Run Code Online (Sandbox Code Playgroud)

按照这里了解如何使用此查询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];
Run Code Online (Sandbox Code Playgroud)

查询在此处详细解释http://www.voidtricks.com/mysql-update-from-select/


小智 5

对于同一张表,

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;
Run Code Online (Sandbox Code Playgroud)