Add to dav1mo,
I prefer to use upper case for keyword and lower case for object names(for example: tables and columns).
It is not necessary to use different correlation names in WHERE clause and in SET clause.
By puttion subqueris in same column positions, it would be easy to compare them to see the ways to rewrite the statement.
2a. You can eliminate concatenation by modifying the predicate to:
Code:
-- AND '10#' || bb1.sl_produkt = h.kbp_produktkennung
AND '10#' = LEFT (h.kbp_produktkennung , 3)
AND bb.sl_produkt = SUBSTR(h.kbp_produktkennung , 4)
3. You can remove the following predicate in SET clause,
because it already specified in WHERE clause.
h. hsp_sachgebiet = 'BASDA'
4. You can remove the predicate "h.kbp_produktkennung IS NOT NULL",
because h.kbp_produktkennung was already compared in EXISTS subquery.
If h. kbp_produktkennung was NULL,
then comparison with the column get unknown and the row would not selected.
Code:
UPDATE hsp_konto_repl h
SET (saldo , prozess_datum)
= (SELECT bs.btr_kapitalsaldo
, bb.dat_von_hist
FROM bsd_basis_fa_a bb
JOIN bsd_saldo_fa_a bs
ON bs.nr_konto = bb.nr_konto
JOIN vwtges0a vg
ON vg.nr_konto = bb.nr_konto
WHERE -- h. hsp_sachgebiet = 'BASDA'
-- AND h. kbp_produktkennung IS NOT NULL
-- AND
vg.k000_kto_key_1 = h.kto_key_1
AND vg.Pers_key_1 = h.Pers_key_1
AND bb.nr_konto = h.kontonummer
-- AND h. hsp_sachgebiet = 'BASDA'
AND bb.sl_kontostatus IN ('30','31','40','41')
AND bb.sl_darlehensart IN ('91')
AND bb.sl_verwzweck IN ('55')
)
WHERE h.hsp_sachgebiet = 'BASDA'
-- AND h.kbp_produktkennung IS NOT NULL
AND EXISTS
(SELECT 0
FROM bsd_basis_fa_a bb
WHERE bb.nr_konto = h.kontonummer
AND bb.sl_kontostatus IN ('30','31','40','41')
AND bb.sl_darlehensart IN ('91')
AND bb.sl_verwzweck IN ('50')
-- AND '10#' || bb1.sl_produkt = h.kbp_produktkennung
AND '10#' = LEFT (h.kbp_produktkennung , 3)
AND bb.sl_produkt = SUBSTR(h.kbp_produktkennung , 4)
)
5. No column of the table "vwtges0a vg" is used in SELECT list.
So, JOIN can be changed to EXISTS predicate.
Although EXISTS might be rewritten to JOIN in optimization process,
it would give more alternative access paths for optimizer.
Code:
UPDATE hsp_konto_repl h
SET (saldo , prozess_datum)
= (SELECT bs.btr_kapitalsaldo
, bb.dat_von_hist
FROM bsd_basis_fa_a bb
JOIN bsd_saldo_fa_a bs
ON bs.nr_konto = bb.nr_konto
WHERE EXISTS
(SELECT 0
FROM vwtges0a vg
WHERE vg.nr_konto = bb.nr_konto
AND vg.k000_kto_key_1 = h. kto_key_1
AND vg.Pers_key_1 = h. Pers_key_1
)
AND bb.nr_konto = h.kontonummer
AND bb.sl_kontostatus IN ('30','31','40','41')
AND bb.sl_darlehensart IN ('91')
AND bb.sl_verwzweck IN ('55')
)
WHERE h.hsp_sachgebiet = 'BASDA'
AND EXISTS
(SELECT 0
FROM bsd_basis_fa_a bb
WHERE bb.nr_konto = h.kontonummer
AND bb.sl_kontostatus IN ('30','31','40','41')
AND bb.sl_darlehensart IN ('91')
AND bb.sl_verwzweck IN ('50')
AND '10#' = LEFT (h.kbp_produktkennung , 3)
AND bb.sl_produkt = SUBSTR(h.kbp_produktkennung , 4)
)
6. I felt following two(similar but different) predicates were strange.
in WHERE clause:
AND bb.sl_verwzweck IN ('50')
in SET clause:
AND bb.sl_verwzweck IN ('55')
If both were same( both were IN ('50'), or both were IN ('55') ),
then you may want to use MERGE statement.
Code:
MERGE hsp_konto_repl h
USING bsd_basis_fa_a bb
ON bb.nr_konto = h.kontonummer
AND bb.sl_kontostatus IN ('30','31','40','41')
AND bb.sl_darlehensart IN ('91')
AND bb.sl_verwzweck IN ('50')
AND '10#' = LEFT (h.kbp_produktkennung , 3)
AND bb.sl_produkt = SUBSTR(h.kbp_produktkennung , 4)
WHEN MATCHED THEN
UPDATE
SET (saldo , prozess_datum)
= (SELECT bs.btr_kapitalsaldo
, bb.dat_von_hist
FROM bsd_saldo_fa_a bs
WHERE bs.nr_konto = bb.nr_konto
AND EXISTS
(SELECT 0
FROM vwtges0a vg
WHERE vg.nr_konto = bb.nr_konto
AND vg.k000_kto_key_1 = h. kto_key_1
AND vg.Pers_key_1 = h. Pers_key_1
)
)