【问题标题】:Group By Column Name As parameter按列名分组作为参数
【发布时间】:2013-06-25 21:23:55
【问题描述】:

假设我有一个名为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中的列名作为参数吗?

【问题讨论】:

  • 除非你使用动态sql,否。
  • 好吧,你可以简化这些SELECT DISTINCT A FROM SALES等。你能补充更多细节吗
  • 必须切换到动态 SQL,然后必须保护自己免受 SQL 注入。如果查询确实是相同的,并且具有相同的“含义”,这让我想知道是否应该有 5 列 - 也许应该有一个列表示可以包含 AE 的某种形式的“类型”,然后是包含“值”的单列(当前包含在 AE 列中) - 换句话说,您的架构设计似乎意外地将实际 data 放入列 names .

标签: sql tsql sql-server-2005 stored-procedures group-by


【解决方案1】:

选项 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 作为字符串参数)

【讨论】:

    【解决方案2】:

    除非所有 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;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-14
      • 2018-10-07
      • 2020-04-16
      • 1970-01-01
      • 2022-01-16
      • 2020-07-18
      相关资源
      最近更新 更多