2017-12-11 11 views
4

トランザクションを記録するテーブルがあります。私は、値2000の丁度4取引を持っているすべてのIDを選択するが、その後その部分が十分に単純である2500別の条件が満たされない限り、条件によって選択します

SELECT t.tuserid, COUNT(*) AS CNT 
    FROM transactions t 
WHERE t.amt = 2000 
GROUP BY t.tuserid 
HAVING CNT = 4; 

の単一のトランザクションを持っているものを除外したいが、私はどのようにわからないんだけどt.amt = 2500のトランザクションを持つ人を効率的に除外します。where句の簡単なサブクエリが最も効率的でしょうか?

SELECT t.tuserid, COUNT(*) AS CNT 
    FROM transactions t 
WHERE t.amt = 2000 
AND t.tuserid NOT IN (SELECT x.tuserid FROM transactions x WHERE x.amt=2500) 
GROUP BY t.tuserid 
HAVING CNT = 4; 

トランザクションテーブルが大きく、サブプロセスがこのプロセスを実行する最も効率的な方法であるかどうかはわかりません。

答えて

3

を使用することができます。サブクエリは外部クエリの「変数」を使用しないため、相関サブクエリではありません。相関関係は通常、外部クエリの各行に対して「実行」され、多くの場合パフォーマンス上の問題です。

サブクエリは外部クエリ呼び出しごとに1回だけ呼び出されます。

さらに、インデックスについて考えることは良い考えです。したがって、where句の中の使用されているフィールドに1つのインデックスを付けることをお勧めします。それから、両方のクエリは、大きなデータテーブルであっても実際には高速でなければならない複雑さのクラスO(log(n))になければなりません。

+0

ありがとうございました。関連する列は索引付けされています(わかりやすくするためにここでは省略しています) – Steve

0

私はこれをテストするためのリソースを持っていないが、サブクエリなしの代替は、はい、サブクエリが、ここで結構ですのみSUM

SELECT 
    t.tuserid, 
    SUM(CASE WHEN t.amt = 2000 THEN 1 ELSE 0 END CASE) AS CNT1, 
    SUM(CASE WHEN t.amt = 2500 THEN 1 ELSE 0 END CASE) AS CNT2 
FROM 
    transactions t 
GROUP BY 
    t.tuserid 
HAVING 
    CNT1 = 4 AND CNT2 = 0; 
関連する問題