Вопрос про использование JOIN в хранимых процедурах

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

Ответить
FRAG Hapoga
Сообщения: 1
Зарегистрирован: 07 фев 2005, 17:10

Вопрос про использование JOIN в хранимых процедурах

Сообщение FRAG Hapoga » 07 фев 2005, 17:31

Есть 2 таблицы:
ARENDA:
ID BIGINT
ARENDA_DET:
ARENDA_ID BIGINT
DATE_BEGIN DATE

ID - первичный ключ, во второй таблице ARENDA_ID - внешний ключ,ссылка на ID из первой таблицы. Во второй таблице хранятся история изменений во времени, типа "такой-то датой - внесено такое-то изменение".

В хранимой процедуре мне надо отловить идентификаторы записей из первой таблицы и дату последних изменений на выбранную дату (передаю параметр CALC_DATE). Пытаюсь сделать следующее:

SELECT ARENDA.ID, AD.DATE_BEGIN FROM ARENDA LEFT JOIN
(SELECT DISTINCT ARENDA_ID, MAX(DATE_BEGIN) AS DATE_BEGIN FROM ARENDA_DET WHERE DATE_BEGIN<=:CALC_DATE GROUP BY ARENDA_ID) AD ON ARENDA.ID=AD.ARENDA_ID

И.... Ни фига не работает!!! FB 1.5

Сразу предупреждаю: FB изучаю после MS SQL и потому некоторые специфические вещи могу не знать. У мелкомягкого сервера в аналогичном случае все работает.

Merlin
Динозавр IB/FB
Сообщения: 1502
Зарегистрирован: 27 окт 2004, 11:44

Re: Вопрос про использование JOIN в хранимых процедурах

Сообщение Merlin » 07 фев 2005, 18:59

FRAG Hapoga писал(а):Есть 2 таблицы:
ARENDA:
ID BIGINT
ARENDA_DET:
ARENDA_ID BIGINT
DATE_BEGIN DATE

ID - первичный ключ, во второй таблице ARENDA_ID - внешний ключ,ссылка на ID из первой таблицы. Во второй таблице хранятся история изменений во времени, типа "такой-то датой - внесено такое-то изменение".

В хранимой процедуре мне надо отловить идентификаторы записей из первой таблицы и дату последних изменений на выбранную дату (передаю параметр CALC_DATE). Пытаюсь сделать следующее:

SELECT ARENDA.ID, AD.DATE_BEGIN FROM ARENDA LEFT JOIN
(SELECT DISTINCT ARENDA_ID, MAX(DATE_BEGIN) AS DATE_BEGIN FROM ARENDA_DET WHERE DATE_BEGIN<=:CALC_DATE GROUP BY ARENDA_ID) AD ON ARENDA.ID=AD.ARENDA_ID

И.... Ни фига не работает!!! FB 1.5

Сразу предупреждаю: FB изучаю после MS SQL и потому некоторые специфические вещи могу не знать. У мелкомягкого сервера в аналогичном случае все работает.
Разврат. Или изврат? Вот до чего доводит избыток возможностей ;) Не нужен здесь join вообще. По классическому SQL это должно выглядеть так:

SELECT AR.ID,
(Select Max(AD.DATE_BEGIN) FROM ARENDA AD
Where AD.ID=AR.ID
And AD.DATE_BEGIN<=:CALC_DATE)
From ARENDA AR

в FB ещё можно так:

SELECT AR.ID,
(Select First 1 AD.DATE_BEGIN FROM ARENDA AD
Where AD.ID=AR.ID
And AD.DATE_BEGIN<=:CALC_DATE
Order By AD.DATE_BEGIN DESC)
From ARENDA AR

второй вариант хорош когда надо извлекать не поле условия (DATE_BEGIN в данном случае), а какое-то другое поле по условию её максимума - в классике уровень вложенности должен быть на единицу больше, потому что надо

SELECT AR.ID,
(Select AA.Column
Where AA.ID=AR.ID
And AA.DATE_BEGIN=
(Select Max(AD.DATE_BEGIN) FROM ARENDA AD
Where AD.ID=AA.ID
And AD.DATE_BEGIN<=:CALC_DATE))
From ARENDA AR

c FIRST же

SELECT AR.ID,
(Select First 1 AD.Column FROM ARENDA AD
Where AD.ID=AR.ID
And AD.DATE_BEGIN<=:CALC_DATE
Order By AD.DATE_BEGIN DESC)
From ARENDA AR

Важно: индексы у нас однонаправленные, так что для эффективности что MAX, что FIRST ... ORDER BY ... DESC нужно наличие descending индекса по DATE_BEGIN.[/code]

Ответить