Подзапросы

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

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

Ответить
Fedja2003
Сообщения: 1
Зарегистрирован: 24 июл 2007, 03:45

Подзапросы

Сообщение Fedja2003 » 24 июл 2007, 06:09

Бываю такие запросы, где нужно подзапросом
вытаскивать разные агрегатные значения. Например:

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

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
Таких подзапросов может быть много.

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

Slavik
Сообщения: 115
Зарегистрирован: 17 янв 2007, 11:52

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

Сообщение Slavik » 24 июл 2007, 07:04

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

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 24 июл 2007, 10:44

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

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

Сообщение Merlin » 24 июл 2007, 12:38

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

Ответить