2009-08-19 2 views
2

私は、ストアドプロシージャに次のように出会っ:ねえ、どのように書くでしょう」、Firebird 1.5の単一のSQLクエリで異なるグループの数を取得しますか?

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) 

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

EDIT:明らかにこれを明確にしていないので、私はFirebird v1.5を使用しています。

+1

私は置きますFirebirdをタグとして使用していますが、明確にするために、Firebird 1.5以降のRDBMSで動作するソリューションに特に関心があります。 :) – Nelson

+0

このコメントは質問の一部となるには十分重要です!私はFirebirdがDBタイプであったことさえ知りませんでした! :) –

+0

@Aviad、私はあなたの推薦に従って質問を更新しました。あなたのコメントをありがとう、私はここで比較的新しいので、タグが十分であると仮定していた(これは実際に私の最初の質問です)。 – Nelson

答えて

1

あなたはFirebirdの1.5を使用しているので、きれいな解決策があるようには思えません。

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

クリーンなソリューションが必要な場合は、Firebird 2.1にアップグレードしてください。さもなければ、あなたが持っているものは、あなたが得ることができるほど良いと思われます。

(いくつかの他のDBMSは、一時テーブルをサポートし、Firebirdの1.5がない場合、あなたは再び一時テーブルをドロップし、一時テーブル内の行をカウントし、一時テーブルに初期データを選択することができます。)

+0

最終的にFB 2.1にアップグレードされました。その間、私は質問に掲載されたコードを使用しました。 – Nelson

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 
) 
+1

DBMSで実際に有効なSQLですか? – Nelson

+0

OracleまたはAccessにはありません。多分SQL Server?しかし、とにかく何かが間違っていると感じます。私はそれをテストするために必要なものがあればいいと思っています。それがうまくいくなら、私はgroup by節を削除するべきだと思う。 – user158017

+0

あなたは正しいです、私の悪い - どういうわけか私はこれがうまくいくことを思い出しました。それを修正してみましょう.. –

-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 
+0

返事をありがとうが、それは私のためにはうまくいかなかった。どのDBMSを使用していますか? – Nelson

+0

私はOracleを使用していますが、これもアクセス時にテストしました。たぶん私はその質問を誤解したでしょうか?私のサブクエリが5行を返す場合、私のoutqueryは "5"を返します。それはあなたが探していたものですか? – user158017

+0

Elizabeth、あなたは完全に要件を理解していますが、このクエリはFirebirdでは残念なことに有効な構文ではありません。 – Nelson

-2

これは、SQL Server上で動作します:

SELECT 
    COUNT(*) 
    FROM (SELECT 
       GroupColumn 
       FROM YourTable 
       WHERE ... 
       GROUP BY GroupColumn 
     ) dt 
+0

私はSQL ServerではなくFirebirdを使用しています。 – Nelson

+0

おそらく、CTEまたは単純なビューfoを使用することができます。派生テーブルを置き換えます。 –

+0

応答に感謝します。ビューの考え方はおそらくうまくいくはずですが、クエリをサポートするためにメタデータをさらに作成したいとは思いません。残念ながら、v1.5ではCTEのサポートはありませんが、明らかにv2.1ではサポートされています。私はFB v1.5がこの情報を照会するエレガントな方法を持っていないと思われ始めています。 – Nelson

関連する問題