Получить количество отдельных групп в одном запросе SQL в Firebird 1.5? - PullRequest
2 голосов
/ 19 августа 2009

Я наткнулся на следующее в хранимой процедуре:

  for
    select 1
    from   scan_queue
    where  ( date_time_locked is null       )
      and  ( scan_seqno >= :varMinScanSeqno )
      and  ( scan_seqno <= :varMaxScanSeqno )
    group by loan_id, collateral_id, insurance_id
    into   varNotUsed
  do
    varItemsToScan = varItemsToScan + 1;

Моей первой мыслью было, что это, вероятно, неэффективный способ подсчета количества групп, но моей второй мыслью было: «Эй, как бы ты записал это в одном запросе? И у меня не было хорошего ответа. (Так что это скорее академический вопрос.) Я не ищу решение, объединяющее идентификаторы, например:

select count(distinct loan_id || collateral_id || insurance_id)
from   scan_queue
where  ( date_time_locked is null       )
  and  ( scan_seqno >= :varMinScanSeqno )
  and  ( scan_seqno <= :varMaxScanSeqno )

Каков наилучший способ запроса этой информации?

РЕДАКТИРОВАТЬ : Так как я, по-видимому, недостаточно ясно дал понять, я использую Firebird v1.5.

Ответы [ 4 ]

1 голос
/ 07 сентября 2009

Поскольку вы используете Firebird 1.5, похоже, не существует чистого решения.

Firebird 2.0 поддерживает нотацию «подзапросов в предложении FROM», которая является основным требованием для ответа на такие вопросы - см. Все остальные ответы.

Итак, если вам нужно чистое решение, обновитесь до Firebird 2.1. В противном случае то, что у вас есть, кажется настолько хорошим, насколько вы можете получить.

(Некоторые другие СУБД поддерживают временные таблицы; если Firebird 1.5 поддерживает, вы можете выбрать исходные данные во временную таблицу, затем подсчитать строки во временной таблице и снова удалить временную таблицу.)

0 голосов
/ 19 августа 2009

не знаю, более или менее эффективно, но подзапрос сделает это

select count(grouping) 
from
( select count(*) as grouping
    from   scan_queue
    where  ( date_time_locked is null       )
      and  ( scan_seqno >= :varMinScanSeqno )
      and  ( scan_seqno <= :varMaxScanSeqno )
    group by loan_id, collateral_id, insurance_id) a
0 голосов
/ 20 августа 2009

это работает на SQL Server:

SELECT
    COUNT(*)
    FROM (SELECT
              GroupColumn
              FROM YourTable
              WHERE ...
              GROUP BY GroupColumn
         ) dt
0 голосов
/ 19 августа 2009

Что не так с простым старым count(distinct ..)?

select count(*) from ( 
select loan_id, collateral_id, insurance_id
from   scan_queue
where  ( date_time_locked is null       )
  and  ( scan_seqno >= :varMinScanSeqno )
  and  ( scan_seqno <= :varMaxScanSeqno )
group by loan_id, collateral_id, insurance_id
)
...