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;

私の最初の考えは、これはおそらくグループの数を数える非効率的な方法だと思いましたが、私の2番目の考えは、「とにかく、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 )

この情報を照会するための最良の方法は何ですか?

編集:私は明らかにこれを十分に明確にしなかったので、私はFirebirdv1.5を使用しています。

4

4 に答える 4

1

Firebird 1.5を使用しているため、クリーンな解決策はないようです。

Firebird 2.0は、このような質問に回答するための基本的な要件である「FROM句のサブクエリ」表記をサポートしています。他のすべての回答を参照してください。

したがって、クリーンなソリューションが必要な場合は、Firebird2.1にアップグレードしてください。そうでなければ、あなたが持っているものはあなたが得ることができるのとほぼ同じくらい良いようです。

(他の一部のDBMSは一時テーブルをサポートしています。Firebird1.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

これはSQLServerで機能します。

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