DB2の更新ステートメントで結合を使用する方法はありますか?
グーグルは本当にこれに私を失望させました
これは私が達成しようとしているおおよそのものです(...明らかに明らかに働いていることを除いて...)
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%'
乾杯
どのプラットフォームをターゲットにしているのか言わないでください。ただし、テーブルをファイルとして参照すると、Linux、UNIX、またはWindows(LUW)でDB2を実行しているのではないと考えることになります。
ただし、DB2 LUWでareである場合は、 [〜#〜] merge [〜#〜] ステートメントを参照してください。
例のステートメントでは、これは次のように記述されます。
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;
注:DB2の場合、SUBSTR関数の3番目の引数は、終了位置ではなく、返すバイト数です。したがって、SUBSTR(a.firstfield、10,20)はCHAR(20)を返します。ただし、SUBSTR(b.anotherfield、1,10)はCHAR(10)を返します。これが意図的に行われたかどうかはわかりませんが、比較に影響する可能性があります。
update
ステートメントの結合は非標準であり、すべてのベンダーでサポートされているわけではありません。あなたがしようとしていることは、サブセレクトで達成できます:
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%'
これを試して、結果を教えてください:
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)
回答の更新 https://stackoverflow.com/a/4184237/565525 :
複数の列が必要な場合は、次のように達成できます:
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%'
ソース: http://www.dbforums.com/db2/1615011-sql-update-using-join-subquery.html#post6257307
ここに私が仕事をしたばかりの良い例があります:
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
)
条件に一致する行のみを更新し、他の行のNULLを更新しないようにするだけです。
update table_one set field_1 = 'ACTIVE' where exists
(select 1 from table_two where table_one.customer = table_two.customer);
DB2/AIX64 9.7.8で動作します
DB2 LUW 9.7の PDATEステートメント のリファレンスドキュメントには、次の例があります。
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'
UPDATEの後の括弧には全選択を含めることができます。つまり、任意の有効なSELECTステートメントをそこに置くことができます。
それに基づいて、私は以下を提案します:
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 )
編集:イアンは正しい。私の最初の本能は、代わりにサブセレクトを試すことでした:
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
)
しかし、連結が機能するかどうかはわかりません。また、部分文字列間に1:1のマッピングがあると想定しています。一致する行が複数ある場合、機能しません。
あなたが尋ねるから
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%'
結合により複数の結果が得られる場合は、このような更新を強制できます
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%'
テンプレートメソッド
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)
)