Страница 1 из 1

Подзапросы

Добавлено: 24 июл 2007, 06:09
Fedja2003
Бываю такие запросы, где нужно подзапросом
вытаскивать разные агрегатные значения. Например:

Код: Выделить всё

select N.*,
  (select count(*) from Products P where P.IDNom = N.IDNom) as NCount,
  (select sum(Kolvo) from Products P where P.IDNom = N.IDNom) as NKolvo,
  (select sum(Kolvo * Price) from Products P where P.IDNom = N.IDNom)
  as NTotal
from Nomenclature N
Таких подзапросов может быть много.

Эти подзапросы выбирают одни и те же записи несколько раз, и суммируют по разным столбцам.
Подскажите можно ли как-нибудь оптимизировать запрос, чтобы выборка была всего один раз. И потом все суммировалось.

Re: Подзапросы

Добавлено: 24 июл 2007, 07:04
Slavik
FB15:

Код: Выделить всё

select n.IDNom,
  max(n.NameNom) as NameNom,... -- и так для всех полей n.*
  count(p.IDNom) as NCount,
  sum(p.Kolvo) as NKolvo,
  sum(p.Kolvo*p.Price) as NTotal
  from Nomenclature n left join Products p on p.IDNom = n.IDNom
  where ... -- фильтр по номенклатуре, если надо
  group by n.IDNom
Такой способ подходит только, если агрегатные значения можно вытащить одним подзапросом (как в примере ниже). Остальные агрегаты придётся вытаскивать твоим способом, или переводить запрос в хранимую процедуру.

В FB20 в выборке можно наконец-то нормально соединять подзапросы:

Код: Выделить всё

select n.*, p.NCount, p.NKolvo, p.NTotal
  from Nomenclature n left join (
         select IDNom, count(*) as NCount,
           sum(Kolvo) as NKolvo, sum(Kolvo*Price) as NTotal
           from Product
           group by IDNom
       ) p on p.IDNom = n.IDNom
  where ... -- фильтр по номенклатуре, если надо
В FB20 есть ещё execute block

Добавлено: 24 июл 2007, 10:44
WildSery
Способов можно придумать значительно больше. Только зачем?
Достаточно было указать на статью по JOIN, и может освежить воспоминания по GROUP BY

Добавлено: 24 июл 2007, 12:38
Merlin
WildSery писал(а):освежить воспоминания по GROUP BY
Сдаёццо мне, что освежать там нечего. Сдаёццо мне, что 2003 - это год рождения :wink: