web-dev-qa-db-fra.com

MySQL - Requête UPDATE basée sur SELECT Query

Je dois vérifier (à partir de la même table) s'il existe une association entre deux événements en fonction de la date et de l'heure.

Un ensemble de données contiendra la date-heure de fin de certains événements et l'autre ensemble de données contiendra la date et l'heure de début pour d'autres événements.

Si le premier événement se termine avant le deuxième événement, j'aimerais les lier.

Ce que j'ai jusqu'ici c'est:

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

Puis je les rejoint:

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

Puis-je alors, en fonction de mon champ validation_check, exécuter une requête UPDATE avec le SELECT imbriqué?

413
John M

Vous pouvez réellement faire cela de deux manières:

Syntaxe de jointure de mise à jour 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

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

Choisissez celui qui vous semble le plus naturel.

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

J'espère que cela fonctionne pour toi.

251
massquote

Facile dans MySQL:

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

Si quelqu'un cherche à mettre à jour des données d'une base de données à une autre, quelle que soit la table ciblée, il doit exister certains critères.

Celui-ci est meilleur et propre pour tous les niveaux:

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! Cela fonctionne très bien!

Avec la compréhension ci-dessus, vous pouvez modifier les champs définis et les critères d'activation pour effectuer votre travail. Vous pouvez également effectuer les vérifications, puis extraire les données dans la ou les tables temporaires, puis exécuter la mise à jour en utilisant la syntaxe ci-dessus en remplaçant vos noms de tables et de colonnes. 

J'espère que cela fonctionne, sinon laissez-moi savoir. Je vais écrire une requête exacte pour vous.

46
KMX
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 ;

J'espère que cela vous aidera dans le cas où vous devez apparier et mettre à jour entre deux tables.

11
Don

J'ai trouvé cette question en cherchant ma propre solution à une jointure très complexe. Ceci est une solution alternative à une version plus complexe du problème, que je pensais être utile. 

J'avais besoin de renseigner le champ product_id dans la table d'activités, où les activités sont numérotées dans une unité et les unités numérotées dans un niveau (identifié à l'aide d'une chaîne ?? N), de sorte que l'on puisse identifier des activités à l'aide d'une SKU, par exemple L1U1A1. Ces SKU sont ensuite stockées dans une table différente. 

J'ai identifié les éléments suivants pour obtenir une liste d'activités_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)

J'ai trouvé que c'était trop complexe à incorporer dans une commande SELECT dans mysql, alors j'ai créé une table temporaire et je l'ai jointe à l'instruction de mise à jour: -

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;

J'espère que quelqu'un trouvera cela utile

11
sibaz
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];
6
bhavik

Vous pouvez mettre à jour les valeurs d'une autre table en utilisant une jointure interne comme ceci

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

Suivez ici pour savoir comment utiliser cette requête http://www.voidtricks.com/mysql-inner-join-update/

ou vous pouvez utiliser select comme sous-requête pour le faire

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

requête expliquée en détail ici http://www.voidtricks.com/mysql-update-from-select/

4
Anand Roshan

Vous pouvez utiliser:

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

Pour la même table,

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
Gnanam pragasam

J'ai eu un problème avec les entrées en double dans une table elle-même. Ci-dessous, les approches fonctionnaient pour moi. Il a également été préconisé par @sibaz.

Enfin, je l'ai résolu en utilisant les requêtes ci-dessous:

  1. La requête de sélection est enregistrée dans une table temporaire

    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 table temporaire est jointe dans la requête de mise à jour.

    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
    )
    

Je ne suis pas très expérimenté avec SQL s'il vous plaît conseiller toute meilleure approche que vous connaissez.

Les requêtes ci-dessus concernent le serveur MySql.

1
Rick

Vérifiez avec la requête ci-dessous.

update tableA A jointure interne table B B sur A.name_a = B.name_b set validation_check = if (start_dts> end_dts, 'VALID', '')) 

0
Anoop Kumar