Первая попытка
На самом деле это невозможно проверить без фактической структуры таблицы и данных, но я внес несколько небольших изменений, которые иногда имеют большое влияние.
Прежде всего, я изменил LEFT JOIN
в with
части на INNER JOIN
. Поскольку вы используете значения a
в предложении WHERE
, он все равно будет функционировать как inner join
, и обычно это происходит намного быстрее, особенно с таким количеством данных и правильными индексами.
Я изменил внутренний CASE
на NVL
, потому что это, по сути, то, что он делает. Не знаю, ускорит ли это все.
Перемещена конкатенация строк из внешнего запроса в часть with
.
Это всего лишь небольшие изменения, которые могут иметь как угодно, так и нет. По крайней мере, вы можете попробовать это перед изменением самой структуры таблицы, хотя в любом случае это может быть хорошей идеей.
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,
t1.cust || t1.curr || LPAD(t1.code, 4, '0') || LPAD(t1.depart, 3, '0') as groupfield
FROM
table1 t1
INNER 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
NVL(ac2.acc_id, t.acc_id)
ELSE
t.groupfield
END) acc_id
FROM
t
LEFT JOIN t ac2 on ac2
ON SUBSTR(ac2.acc_id, 1, 6) = '000' || LPAD(t.depart, 3, '0')
GROUP BY
(CASE WHEN t.as = '000000' THEN
NVL(ac2.acc_id, t.acc_id)
ELSE
t.groupfield
END)
Вторая попытка
Посмотрев немного больше на ваш запрос, я задаюсь вопросом, не можете ли вы просто сделать его одним / простым запросом вместо использования with
. Я думаю, что сначала присоединившись к Accs, а затем снова оставив присоединение к Accs с дополнительным условием, вы действительно хороший путь.
SELECT
MAX(t1.s_id) AS s_id,
CASE WHEN t.as = '000000' THEN
NVL(a2.acc_id, a.acc_id)
ELSE
t1.cust || t1.curr || LPAD(t1.code, 4, '0') || LPAD(t1.depart, 3, '0')
END AS acc_id
FROM
table1 t1
INNER JOIN Accs a
ON SUBSTR(a.acc_id, 7, 12) = t1.curr || LPAD(t1.code, 4, '0') || LPAD(t1.depart, 3, '0')
AND a.month = 11 AND a.year = 2011
LEFT JOIN Accs a2
ON SUBSTR(a2.acc_id, 7, 12) = t1.curr || LPAD(t1.code, 4, '0') || LPAD(t1.depart, 3, '0')
AND a2.month = 11 AND a2.year = 2011
AND SUBSTR(a2.acc_id, 1, 6) = '000' || LPAD(t1.depart, 3, '0')
WHERE
t1.sdate = '20.11.2011' AND t1.stype = 'A'
GROUP BY
CASE WHEN t.as = '000000' THEN
NVL(a2.acc_id, a.acc_id)
ELSE
t1.cust || t1.curr || LPAD(t1.code, 4, '0') || LPAD(t1.depart, 3, '0') as groupfield
END AS acc_id