2

我在存储过程中遇到了以下问题:

  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;

我的第一个想法是,这可能是一种计算组数的低效方法,但我的第二个想法是,“嘿,无论如何,你将如何在单个查询中编写它?” 我没有一个好的答案。(所以这更像是一个学术问题。)我不是在寻找连接 ID 的解决方案,如下所示:

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

4 回答 4

1

由于您使用的是 Firebird 1.5,因此似乎没有一个干净的解决方案。

Firebird 2.0 支持“FROM 子句中的子查询”表示法,这是回答此类问题的基本要求 - 请参阅所有其他答案。

因此,如果您需要一个干净的解决方案,请升级到 Firebird 2.1。否则,你所拥有的似乎与你能得到的一样好。

(其他一些 DBMS 支持临时表;如果 Firebird 1.5 支持,您可以将初始数据选择到临时表中,然后计算临时表中的行数,然后再次删除临时表。)

于 2009-09-07T08:38:48.120 回答
0

普通的旧有什么问题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
)
于 2009-08-19T19:51:21.850 回答
-2

不知道它是否或多或少有效,但子查询会做到这一点。

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
于 2009-08-19T19:54:08.490 回答
-2

这适用于 SQL Server:

SELECT
    COUNT(*)
    FROM (SELECT
              GroupColumn
              FROM YourTable
              WHERE ...
              GROUP BY GroupColumn
         ) dt
于 2009-08-19T20:06:15.173 回答