0

というテーブルがあるとしましょうSales

次のようなストアドプロシージャもあります。

SELECT A FROM SALES GROUP BY A

SELECT B FROM SALES GROUP BY B

SELECT C FROM SALES GROUP BY C

SELECT D FROM SALES GROUP BY D

SELECT E FROM SALES GROUP BY E

SELECTそのストアド プロシージャ内のステートメントの数を 1 つだけに減らすことはできますか?

つまり、group by の列名をパラメーターとして使用することは可能ですか?

4

2 に答える 2

3

オプション A - 動的 SQL を使用できます。

DECLARE @sql NVARCHAR(MAX)
SELECT 'SELECT ' + @col + ' FROM SALES GROUP BY ' + col + '; '
EXEC (@sql)

オプション B - 使用できますCASE

SELECT CASE @col WHEN 'A' THEN A
                 WHEN 'B' THEN B
                 WHEN 'C' THEN C
                 WHEN 'D' THEN D
                 WHEN 'E' THEN E
         END
FROM SALES
GROUP BY CASE @col WHEN 'A' THEN A
                   WHEN 'B' THEN B
                   WHEN 'C' THEN C
                   WHEN 'D' THEN D
                   WHEN 'E' THEN E
         END

(どちらのオプションも @col を文字列パラメーターとして受け取ります)

于 2013-06-28T07:10:21.867 に答える
1

戻り値の型が毎回変わるため、5 つの列すべてが互換性のあるデータ型でない限り、あなたのアイデアはストアド プロシージャの契約を破ります。これは、この戻り値の型の変更に対処するためのより複雑なクライアント コードを意味します。

それらがすべて同じデータ型である場合、動的SQLを避けるためにこれを使用できます

SELECT DISTINCT
   CASE @param
     WHEN @param = 'A' THEN A
     WHEN @param = 'B' THEN B
     WHEN @param = 'C' THEN C
     WHEN @param = 'D' THEN D
     WHEN @param = 'E' THEN E
   END
FROM
   SALES;

それでも効率的ではありません。

SUM や COUNT などの異なる集計が必要な場合は、データ型の互換性や動的 SQL を使用せずにこれを行う方法が他にもあります。では、とにかく解決したい実際の問題は何ですか?

たとえば、これは、クライアントでAからEをきれいに選択できることを意味します

SELECT DISTINCT
    COUNT(*) OVER (GROUP BY A) AS cntA,
    COUNT(*) OVER (GROUP BY B) AS cntB,
    COUNT(*) OVER (GROUP BY C) AS cntC,
    COUNT(*) OVER (GROUP BY D) AS cntD,
    COUNT(*) OVER (GROUP BY E) AS cntE
FROM
    SALES;
于 2013-06-28T07:10:23.470 に答える