I have 2 tables. Table “Accs” contains 9 million rows (3 columns: acc_id, month, year).
First I need to extract the records that contain the partial entry of account number,
and then in these records to find the complete match, if not – then the first partial match
WITH t AS (
SELECT a.acc_id,
t1.as,
t1.cust,
t1.curr,
t1.code,
t1.depart,
t1.sdate,
t1.stype,
t1.amount,
t1.s_id
FROM table1 t1
LEFT JOIN Accs a
ON SUBSTR(a.acc_id,7,12)=t1.curr||LPAD(t1.code,4,'0')||LPAD(t1.depart,3,'0')
WHERE t1.sdate='20.11.2011' AND t1.stype='A' AND a.month=11 ANd a.year=2011)
SELECT MAX(t.s_id),
(CASE WHEN t.as='000000'
THEN (CASE WHEN ac2.acc_id IS NOT NULL THEN ac2.acc_id ELSE t.acc_id END)
ELSE t.cust||t.curr||LPAD(t.code,4,'0')||LPAD(t.depart,3,'0') END) acc_id
FROM t
LEFT JOIN (SELECT t.acc_id FROM t) ac2
ON SUBSTR(ac2.acc_id,1,6)='000'||LPAD(t.depart,3,'0')
GROUP BY
(CASE WHEN t.as='000000'
THEN (CASE WHEN ac2.acc_id IS NOT NULL THEN ac2.acc_id ELSE t.acc_id END)
ELSE t.cust||t.curr||LPAD(t.code,4,'0')||LPAD(t.depart,3,'0') END)
This query takes a long time. Whether correctly I do?
First attempt
Can’t really test it without having your actual table structure and data, but I’ve made a few minor changes that do sometimes have big impact.
First of all, I changed the
LEFT JOINin thewithpart to anINNER JOIN. Since you use values ofain theWHEREclause, it would function as aninner joinanyway, and it is usually a lot faster, especially with this amount of data and proper indexes.I changed the inner
CASEtoNVL, because that’s essentially what it does. Don’t know if that would speed things up.Moved the string concatenation from the outer query to the
withpart.These are just small changes that may have anywhere from no to quite some effect. At least you can try these before altering the table structure itself, although it may be a good idea to do that anyway.
Second attempt
After looking a little more into your query, I wonder if you cannot just make it a single/simple query instead of using
with. I think by first inner joining Accs and then left joining Accs again with the extra condition, you’re a good way to go really.