2009-08-11 17 views
335

Necesito verificar (desde la misma tabla) si hay una asociación entre dos eventos en función de la fecha y hora.MySQL - Consulta de actualización basada en SELECT Query

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

Si el primer evento se completa antes del segundo evento, 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 les unen:

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, basado en mi campo validation_check, ejecutar una consulta de actualización con el anidada SELECT?

+1

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

Respuesta

573

En realidad se puede hacer esto de dos maneras:

actualización de MySQL sintaxis de unión:

update tableA a 
left join tableB b on 
    a.name_a = b.name_b 
set 
    validation_check = if(start_dts > end_dts, 'VALID', '') 

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

Recogida lo que uno parece más natural para ti.

+75

El primer formulario (actualización con unión) va a ser * mucho * más eficiente que el segundo. El primero haría una sola unión, mientras que el segundo ejecutaría la consulta de selección para cada fila de la tabla A. – ColinM

+12

Para el primer ejemplo, ¿no debería usar una unión interna? ¿No se unirá a la izquierda el resultado de que validation_check se establece en nulo para los registros de la tabla A sin un registro tableB correspondiente? – Cerin

+3

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

43

Si alguien está tratando de actualizar los datos de una base de datos a otra, independientemente de 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 genial!

Según lo entendido anteriormente, puede modificar los campos establecidos y los criterios "activados" para hacer su trabajo. También puede realizar 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 la tabla y columna.

Espero que funcione, si no, hágamelo saber. Escribiré una consulta exacta para ti.

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

Espero que esto funcione para usted.

+2

Esta es, con mucho, la consulta más rápida. Editar: Tener dest con 22K filas y src con 4K filas, tomó menos de 1 segundo para completar, mientras que la respuesta superior durante 60 segundos. –

+1

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

+0

Buena consulta. 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 ; 

Espero que esto lo ayude en un caso en el que tiene que coincidir y actualizar entre dos tablas.

9

Encontré esta pregunta al buscar mi propia solución para una unió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.

Necesité rellenar 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 (identificado con una cadena ?? N), de modo que se pueden identificar actividades usando una SKU es decir, L1U1A1. Esas SKU se almacenan en una tabla diferente.

que identifican 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) 

encontré que eso era demasiado complejo para incorporar en un SELECT dentro de MySQL, así que creé una tabla temporal, y se unió a que con la instrucció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

66

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 
+0

tengo una pregunta similar, y me pregunto si puedo hacer algo similar con mi situación: https://stackoverflow.com/questions/47948052/mysql-wordpress-records-update – MagicMiles

4

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

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 utilizar selecto 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 explica en detalles aquí 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

que puede utilizar:

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

Para una 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; 
Cuestiones relacionadas