web-dev-qa-db-fra.com

INNER JOIN dans UPDATE SQL pour DB2

Est-il possible d'utiliser des jointures dans les instructions de mise à jour pour DB2?

Google m'a vraiment laissé tomber sur celui-ci

C’est à peu près ce que j’essaie d’atteindre (... sauf évidemment que je travaille ...)

update file1 inner join file2                                 
       on substr(file1.firstfield,10,20) = substr(file2.anotherfield,1,10)                                                                    
set file1.firstfield = ( 'BIT OF TEXT' concat file2.something )                                                                             
where file1.firstfield like 'BLAH%'                             

À votre santé

12
Hamish

Vous ne dites pas quelle plate-forme vous ciblez. Faire référence à des tables en tant que fichiers, cependant, m'amène à penser que vous n'exécutez pas DB2 sous Linux, UNIX ou Windows (LUW).

Toutefois, si vous êtes sous DB2 LUW, reportez-vous à la déclaration MERGE

Pour votre exemple d'instruction, ceci serait écrit comme suit:

merge into file1 a
   using (select anotherfield, something from file2) b
   on substr(a.firstfield,10,20) = substr(b.anotherfield,1,10)
when matched and a.firstfield like 'BLAH%'
   then update set a.firstfield = 'BIT OF TEXT' || b.something;

Remarque: pour DB2, le troisième argument de la fonction SUBSTR est le nombre d'octets à renvoyer, pas la position finale. Par conséquent, SUBSTR (a.firstfield, 10,20) renvoie CHAR (20). Cependant, SUBSTR (b.anotherfield, 1,10) renvoie CHAR (10). Je ne sais pas si cela a été fait exprès, mais cela peut affecter votre comparaison.

8
Ian Bjorhovde

Les jointures dans les instructions update sont non standard et ne sont pas prises en charge par tous les fournisseurs. Ce que vous essayez de faire peut être accompli avec une sous-sélection:

update
  file1
set
  firstfield = (select 'stuff' concat something from file2 where substr(file1.field1, 10, 20) = substr(file2.xxx,1,10) )
where
  file1.foo like 'BLAH%'
7
Donnie

Essayez ceci et dites-moi les résultats:

UPDATE File1 AS B                          
SET    b.campo1 = (SELECT DISTINCT A.campo1
                   FROM  File2 A           
                   INNER JOIN File1      
                   ON A.campo2 = File1.campo2 
                   AND A.campo2 = B.campo2) 
6
eduardo

Voici un bon exemple de quelque chose que je viens de faire:

update cac c
set ga_meth_id = (
    select cim.ga_meth_id 
    from cci ci, ccim cim 
    where ci.cus_id_key_n = cim.cus_id_key_n
    and ci.cus_set_c = cim.cus_set_c
    and ci.cus_set_c = c.cus_set_c
    and ci.cps_key_n = c.cps_key_n
)
where exists (
    select 1  
    from cci ci2, ccim cim2 
    where ci2.cus_id_key_n = cim2.cus_id_key_n
    and ci2.cus_set_c = cim2.cus_set_c
    and ci2.cus_set_c = c.cus_set_c
    and ci2.cps_key_n = c.cps_key_n
)
3
Justin

Mise à jour de la réponse https://stackoverflow.com/a/4184237/565525

si vous voulez plusieurs colonnes, cela peut être réalisé comme ceci:

update file1
set
  (firstfield, secondfield) = (
        select 'stuff' concat 'something from file2', 
               'some secondfield value' 
        from file2
        where substr(file1.field1, 10, 20) = substr(file2.xxx,1,10) )
where
  file1.foo like 'BLAH%'

Source: http://www.dbforums.com/db2/1615011-sql-update-using-join-subquery.html#post6257307

3
Robert Lujo

Juste pour mettre à jour uniquement les lignes qui correspondent aux conditions et éviter de mettre à jour les valeurs NULL dans les autres lignes:

update table_one set field_1 = 'ACTIVE' where exists 
(select 1 from table_two where table_one.customer = table_two.customer);

Cela fonctionne dans un DB2/AIX64 9.7.8 

1
Antonio

La documentation de référence de l'instruction UPDATE sur DB2 LUW 9.7 donne l'exemple suivant:

   UPDATE (SELECT EMPNO, SALARY, COMM,
     AVG(SALARY) OVER (PARTITION BY WORKDEPT),
     AVG(COMM) OVER (PARTITION BY WORKDEPT)
     FROM EMPLOYEE E) AS E(EMPNO, SALARY, COMM, AVGSAL, AVGCOMM)
   SET (SALARY, COMM) = (AVGSAL, AVGCOMM)
   WHERE EMPNO = '000120'

Les parenthèses après UPDATE peuvent contenir une sélection complète, ce qui signifie que toute instruction SELECT valide peut y aller.

Sur cette base, je suggérerais ce qui suit:

UPDATE (
  SELECT
    f1.firstfield,
    f2.anotherfield,
    f2.something
  FROM file1 f1
  WHERE f1.firstfield like 'BLAH%' 
  INNER JOIN file2 f2
  ON substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
)
AS my_files(firstfield, anotherfield, something)
SET
  firstfield = ( 'BIT OF TEXT' || something )

Edit: Ian a raison. Mon premier instinct a été d'essayer à la place les sous-élus:

UPDATE file1 f1
SET f1.firstfield = ( 'BIT OF TEXT' || (
  SELECT f2.something
  FROM file2 f2
  WHERE substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
))
WHERE f1.firstfield LIKE 'BLAH%' 
AND substr(f1.firstfield,10,20) IN (
  SELECT substr(f2.anotherfield,1,10)
  FROM file2 f2
)

Mais je ne suis pas sûr si la concaténation fonctionnerait. Cela suppose également qu'il existe une correspondance 1: 1 entre les sous-chaînes. Si plusieurs lignes correspondent, cela ne fonctionnera pas.

0
Leons

pour vous demander 

update file1 f1
set file1.firstfield=
(
select 'BIT OF TEXT' || f2.something
from file2 f2
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
)
where exists
(
select * from file2 f2
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
)
and f1.firstfield like 'BLAH%'

si rejoindre donne plusieurs résultats vous pouvez forcer la mise à jour comme ceci

update file1 f1
set file1.firstfield=
(
select 'BIT OF TEXT' || f2.something
from file2 f2
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
fetch first rows only
)
where exists
(
select * from file2 f2
where substr(f1.firstfield,10,20) = substr(f2.anotherfield,1,10)
)
and f1.firstfield like 'BLAH%' 

méthode de template

update table1 f1
set (f1.field1, f1.field2, f1.field3, f1.field4)=
(
select f2.field1, f2.field2, f2.field3, 'CONSTVALUE'
from table2 f2
where (f1.key1, f1.key2)=(f2.key1, f2.key2) 
)
where exists 
(
select * from table2 f2
where (f1.key1, f1.key2)=(f2.key1, f2.key2)
) 
0
Esperento57