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将该存储过程中的语句数量减少到只有一个吗?

换句话说,是否可以将 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 回答