简体   繁体   English

按列名称分组作为参数

[英]Group By Column Name As parameter

Let's say that I have a table called Sales . 假设我有一个名为Sales的表。

I also have a stored procedures something like this: 我也有一个存储过程是这样的:

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

Can I reduce the number of SELECT statements in that stored procedure to just one? 我可以将存储过程中的SELECT语句数量减少到一个吗?

In other words is it possible to use the column name in group by as a parameter? 换句话说,可以将group by中的列名用作参数吗?

Option A - you can use dynamic sql: 选项A-您可以使用动态sql:

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

Option B - you can use CASE 选项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

(Both options receive @col as string parameter) (两个选项都将@col作为字符串参数接收)

Your idea breaks the stored procedure contract unless all 5 columns are compatible datatypes because the return type changes each time. 除非所有5列都是兼容的数据类型,否则您的想法都会破坏存储过程协定,因为返回类型每次都会更改。 This means more complex client code to deal with this return type change 这意味着需要更复杂的客户端代码来处理此返回类型更改

If they are all the same datatype, to avoid dynamic SQL you can use this 如果它们都是相同的数据类型,为了避免使用动态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;

It still isn't efficient though. 虽然它仍然不是很有效。

If you want different aggregates like SUM or COUNT there are other ways to do this without datatype compatibility or dynamic SQL. 如果您想要不同的聚合(例如SUM或COUNT),则可以使用其他方法来实现此目的而无需数据类型兼容性或动态SQL。 So, what is the actual problem you want to solve anyway? 那么,您要解决的实际问题是什么?

For example, this means you can pick A to E in the client cleanly 例如,这意味着您可以在客户端中干净地选择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;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM