MySQL: consulta ACTUALIZAR basada en consulta SELECCIONAR

Necesito verificar (de la misma tabla) si existe una asociación entre dos eventos según la fecha y la hora.

Un conjunto de datos contendrá la fecha y hora de finalización de ciertos eventos y el otro conjunto de datos contendrá la fecha y hora de inicio de otros eventos.

Si el primer evento se completa antes del segundo, me gustaría vincularlos.

Lo que tengo hasta ahora es:

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

Entonces me uno a ellos:

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

¿Puedo entonces, según mi campo validation_check, ejecutar una consulta ACTUALIZAR con SELECT anidado?

preguntado el 11 de agosto de 09 a las 17:08

¿No estoy seguro de lo que estás preguntando? ¿Está tratando de averiguar cómo hacer una actualización con SQL Select? -

11 Respuestas

En realidad, puede hacer esto de dos maneras:

Sintaxis de unión de actualización de 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

Sintaxis 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)

Elija el que le parezca más natural.

respondido 26 nov., 18:00

El primer formulario (actualizar con unirse) será un montón más eficiente que el segundo. El primero haría una única combinación, mientras que el segundo ejecutaría la consulta de selección para cada fila de tableA. - ColinM

Para el primer ejemplo, ¿no debería usar una combinación interna? ¿La unión izquierda no dará como resultado que validation_check se establezca en nulo para los registros tableA sin un registro tableB correspondiente? - Cerín

@Cerin sí, eso me pasó a mí. ¡Debería ser una unión interna! O simplemente déjelo como unirse. Si no tiene una combinación interna, la combinación izquierda significa que todos los registros de la tablaA se actualizarán. ¡Esto es muy peligroso! - CMCDragonkai

Gracias por la primera (y). Si bien esta respuesta tiene más de 7 años. No puedo creer por qué nadie ha dicho que el segundo no funciona en alguna base de datos como MySQL. Obtendrá este error: You can't specify target table ___ for update in FROM clause SQL.sql - Jugali Lakota

Además, tenga en cuenta que hasta hace poco, el primer enfoque no funcionaba con MySQL cuando tableA = tableB. Está obligado a crear una tabla temporal para almacenar el resultado intermedio. (tuve que escribir una consulta similar para un script de migración) - svvac

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

Espero que esto funcione para usted.

Respondido 20 Jul 18, 10:07

Esta es, con mucho, la consulta más rápida. Editar: Teniendo dest con 22K filas y src con 4K filas, tardó menos de 1 segundo en completarse, mientras que la respuesta superior más de 60 segundos. - chris dev

Sí, esta es la consulta más rápida, por cierto, también puede agregar la cláusula WHERE - robinmag

más rápido no siempre implica bueno, esta actualización no funcionará en todos los casos, de hecho algunos casos tendrás un comportamiento inesperado, todo esto es por eso que no poner una condición y que no sea un join - Emiliano

Fácil en MySQL:

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

Respondido 06 Jul 17, 11:07

Si alguien está buscando actualizar datos de una base de datos a otra sin importar la tabla a la que se dirijan, debe haber algunos criterios para hacerlo.

Este es mejor y limpio para todos los niveles:

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! ¡Funciona muy bien!

Con la comprensión anterior, puede modificar los campos establecidos y los criterios "on" para hacer su trabajo. También puede realizar las comprobaciones, luego extraer los datos en la (s) tabla (s) temporal (es) y luego ejecutar la actualización usando la sintaxis anterior reemplazando los nombres de su tabla y columna.

Espero que funcione, si no, avísame. Escribiré una consulta exacta para ti.

respondido 25 nov., 18:16

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 ;

Espero que esto le ayude en un caso en el que tenga que hacer coincidir y actualizar entre dos tablas.

Respondido el 05 de Septiembre de 18 a las 10:09

Encontré esta pregunta al buscar mi propia solución para una combinación muy compleja. Esta es una solución alternativa, a una versión más compleja del problema, que pensé que podría ser útil.

Necesitaba completar el campo product_id en la tabla de actividades, donde las actividades están numeradas en una unidad y las unidades están numeradas en un nivel (identificadas usando una cadena ?? N), de modo que uno pueda identificar las actividades usando un SKU, es decir, L1U1A1. Luego, esos SKU se almacenan en una tabla diferente.

Identifiqué lo siguiente para obtener una lista de 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)

Descubrí que eso era demasiado complejo para incorporarlo en un SELECT dentro de mysql, así que creé una tabla temporal y la uní con la declaración de actualización: -

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;

Espero que alguien encuentre esto útil

Respondido 31 Oct 18, 12:10

Es posible que dos consultas no den un resultado coherente en un entorno de subprocesos múltiples. - Donald

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

respondido 21 nov., 16:05

Puede actualizar los valores de otra tabla usando una combinación interna como esta

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

Siga aquí para saber cómo utilizar esta consulta http://www.voidtricks.com/mysql-inner-join-update/

o puede usar seleccionar como subconsulta para hacer esto

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

consulta explicada en detalle aquí http://www.voidtricks.com/mysql-update-from-select/

Respondido 15 Oct 15, 01:10

Puedes usar:

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

respondido 03 mar '17, 06:03

Para la misma mesa,

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;

Respondido el 01 de diciembre de 17 a las 16:12

Tuve un problema con las entradas duplicadas en una tabla. A continuación se muestran los enfoques que me funcionaron. También ha sido defendido por @sibaz.

Finalmente lo resolví usando las siguientes consultas:

  1. La consulta de selección se guarda en una tabla temporal

    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. La tabla temporal se une a la consulta de actualización.

    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
    )
    

No tengo mucha experiencia con SQL, por favor aconseje cualquier enfoque mejor que conozca.

Las consultas anteriores son para el servidor MySql.

contestado el 11 de mayo de 18 a las 09:05

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.