перевести/упростить запрос FB to Oracle

kill-still

Запрос в фаербёрде:

SELECT p.ID,
(SELECT first 1 (CASE
WHEN (c.exception IS NULL)
THEN 1
ELSE 0
END)
FROM child c
WHERE c.parent_id = p.ID
ORDER BY c.exception NULLS FIRST) AS x
FROM parent p

добавляет к таблице parent мнимый столбец с информацией о связанных записях из child
1 - есть незакрытые строки 0 - нет NULL - нет строк вообще. (значения по барабану, главное различать эти три состояния)
Долго извращался, в итоге получился такой монстр:

SELECT p.ID,
(SELECT (CASE
WHEN c.exception_date IS NULL
THEN 1
ELSE 0
END)
FROM (SELECT tmp.parent_id , tmp.exception,
(ROW_NUMBER OVER (PARTITION BY tmp.parent_id ORDER BY tmp.exception NULLS FIRST AS rn
FROM child tmp) c
WHERE c.parent_id = p.ID AND c.rn = 1) AS tmp
FROM parent p

чую что перемудрил. Может кому не лень глянуть.

Gasparfx

CASE WHEN c.exception_date IS NULL THEN 1 ELSE 0 END
как минимум это можно заменить на nvl2(c.exception, 0,1)

Gasparfx

Решение:
 
SELECT p.id, q.fl
FROM parent p, (SELECT parent_id, DECODE(COUNT(NVL(exception,1 - COUNT(exception0,0,1) AS fl FROM child GROUP BY parent_id) q
WHERE p.id = q.parent_id(+)
ORDER BY p.id

kill-still

совсем скурился с этим FB 1.5 (там нет возможности подзапросы в FROM писать забыл про джойны о.О

kill-still

Отличная идея, спасибо! :)

mbolik1

 SELECT p.ID,
(SELECT DECODE(count(*0,0,1)
FROM child c
WHERE c.parent_id = p.ID
AND c.exception IS NULL) AS x
FROM parent p

hprt

count же будет 0, если записей нет совсем. надо с max/min делать, как я тебе писал
а в оракле отработает что-нить типа select p.id, (select max(case when exception blah blah end) from child where parent = p.id) from parent ?

kill-still

Твой запрос кстати будет на порядок дороже, т.к. он будет дважды индекс parent_id обрабатывать - сначала при HASH GROUP BY, потом при HASH JOIN RIGHT OUTER. С утра-то намного лучше соображается. :grin:
By the way: что-то не догоню, чем различается
PLAN (C ORDER FK_PARENT_TO_CHILD)
и
PLAN SORT A INDEX (FK_PARENT_TO_CHILD

kill-still

что-то в таком роде и написал, с учётом того, что exception это timestamp.

hprt

Не совсем понимаю, как тип timestamp влияет на то, что я написал. Неприменим оператор blah blah? :)

kill-still

Ну, я же всё сильно упростил, чтобы понятно было. Это же всего лишь небольшая часть крокодила. :)

mbolik1

count же будет 0, если записей нет совсем
Я оказывается пропустил момент что если записей нет то нужно выводить null. Тогда MAX или MIN.
Оставить комментарий
Имя или ник:
Комментарий: