【问题标题】:SQL: Group By with Case Statement for multiple fieldsSQL:分组依据与多个字段的案例语句
【发布时间】:2013-05-13 01:16:12
【问题描述】:

我正在尝试使用 CASE 语句编写 GROUP BY 子句,以便可以根据查询中的参数值有条件地进行 GROUP BY。这是我正在使用的查询(显着缩短),我不断收到“RVPname 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。并且 DVPname 无效并且 AEname 无效。

SELECT
DVPname, RVPname, AEname, Dealer, Product, Distribution, 

CASE WHEN @LEVEL = 'DVP' THEN DVPname
WHEN @LEVEL = 'RVP' THEN RVPname
WHEN @LEVEL = 'AE' THEN AEname
END AS NAME

..........other code here.....

GROUP BY Product, Distribution,
CASE WHEN @LEVEL = 'RVP' THEN AEname WHEN @LEVEL = 'DVP' THEN RVPname WHEN @LEVEL= 'AE' THEN Dealer END

--有谁知道如何做我想要完成的事情。当 LEVEL='DVP' 我想 GROUP BY RVPname,当 LEVEL='RVP' 我想 GROUP BY AEname....有意义吗?

【问题讨论】:

  • “此处的其他代码”部分是否包含任何聚合,例如 sum()、min() 等?如果是这样,您必须按 select 子句中的所有内容进行分组。如果不是,group by 子句的目的是什么?
  • Group by case 与 select case 不同;它们应该相同才能正常工作。
  • 其他代码只包含计算字段。
  • 再一次,如果没有聚合,group by 子句的目的是什么?

标签: sql group-by case


【解决方案1】:

没有聚合的 group by 查询(例如您的查询)仅对删除重复项有用。因此,您的选择是为 select 子句中不在 group by 中的列添加聚合,或者使用查询删除重复项。

以下代码删除了所有仅在 group by 语句中有条件的列(DVPname、RVPname、AEname、Dealer)(只要它们不在 group by 中但在 select 中,就会出错)。它还将名称添加到 group by,以便它可以在 select 子句中。

SELECT
Product, Distribution,
CASE 
    WHEN @LEVEL = 'DVP' THEN DVPname
    WHEN @LEVEL = 'RVP' THEN RVPname
    WHEN @LEVEL = 'AE' THEN AEname
END AS NAME,
CASE 
     WHEN @LEVEL = 'RVP' THEN AEname 
     WHEN @LEVEL = 'DVP' THEN DVPname 
     WHEN @LEVEL= 'AE' THEN Dealer 
END 

..........other code here.....

GROUP BY Product, Distribution, 
CASE 
    WHEN @LEVEL = 'DVP' THEN DVPname
    WHEN @LEVEL = 'RVP' THEN RVPname
    WHEN @LEVEL = 'AE' THEN AEname
END,
CASE 
     WHEN @LEVEL = 'RVP' THEN AEname 
     WHEN @LEVEL = 'DVP' THEN DVPname 
     WHEN @LEVEL= 'AE' THEN Dealer 
END 

【讨论】:

  • 这将解决 RVPname 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中
【解决方案2】:

您需要使用聚合函数(例如AVG()SUM())选择所有不在GROUP BY 子句中的列。否则,数据库不知道如何处理分组记录返回的多个条目。

例如,您的 select 语句应该以这样的开头:

SELECT
SUM(DVPname), AVG(RVPname),

如果它们是文本条目并且您知道它们都是相同的,您也可以将它们添加到GROUP BY 子句中。

GROUP BY DVPname, RVPname, AEname, Dealer, Product, Distribution

此外,这里有一个适合您的分组的好格式:

GROUP BY
CASE WHEN @SortColumn = '0'
THEN [id] END,
CASE WHEN @SortColumn = '1'
THEN [name] END;

【讨论】:

  • 所以你要么有GROUP BY null, name要么GROUP BY id, null,对吧?
  • 它可以是GROUP BY [id]GROUP BY [name]。此外,您可以将所有这些组合成GROUP BY DVPname, RVPname, AEname, Dealer, Product, Distribution, CASE WHEN @SortColumn = '0' THEN [id] END, CASE WHEN @SortColumn = '1' THEN [name] END;
  • 不。您没有使用ELSE,而是列出了两个CASE 语句,用逗号分隔。
【解决方案3】:

如果您只想要条件 group by,那么我建议使用子查询:

select name, . ..
from (select (CASE WHEN @LEVEL = 'DVP' THEN DVPname
                   WHEN @LEVEL = 'RVP' THEN RVPname
                   WHEN @LEVEL = 'AE' THEN AEname
              END
             ) AS NAME, t.*
      from t
     ) t
group by name;

但是,您会丢失所需的所有其他字段。在大多数数据库中,您不能在 select 中包含列,除非它们被聚合或在 group by 子句中。这是从列中获取任意值的替代方法:

SELECT min(DVPname), min(RVPname), min(AEname), min(Dealer), min(Product),
       min(Distribution),
       . . .
from (select (CASE WHEN @LEVEL = 'DVP' THEN DVPname
                   WHEN @LEVEL = 'RVP' THEN RVPname
                   WHEN @LEVEL = 'AE' THEN AEname
              END
             ) AS NAME, t.*
      from t
     ) t
group by name;

这将返回列的最小值。

【讨论】:

    【解决方案4】:

    我知道两种方法:GROUP BY(Case 语句 1,Case 语句 2)和子查询。我确定每种方法将占用多少行,然后以此为基础制定我的流程。

    例如。 (分组):

        SELECT
            CASE
                WHEN (situation A)
                THEN (result A)
                WHEN (situation B)
                THEN (result B)
            END column1,
            CASE
                WHEN (situation C)
                THEN (result C)
                WHEN (situation D)
                THEN (result D)
            END column2,
            SUM(AMOUNT) as TotalAMOUNT
        FROM aTable
        GROUP BY 
            CASE
                WHEN (situation A)
                THEN (result A)
                WHEN (situation B)
                THEN (result B)
            END,
            CASE
                WHEN (situation C)
                THEN (result C)
                WHEN (situation D)
                THEN (result D)
            END
    

    例如。 (子查询)

        SELECT
            Column1,
            Column2,
            SUM(AMOUNT) as TotalAMOUNT
        FROM
            (
            SELECT
                CASE
                    WHEN (situation A)
                    THEN (result A)
                    WHEN (situation B)
                    THEN (result B)
                END column1,
                CASE
                    WHEN (situation C)
                    THEN (result C)
                    WHEN (situation D)
                    THEN (result D)
                END column2,
                AMOUNT
            FROM aTable
            )CaseTable
        GROUP BY Column1, Column2
        ORDER BY Column1 asc, SUM(AMOUNT) 
    

    我认为要记住的重要一点是,除了分组内容之外,您不能包含其他详细信息。在以上两个示例中,您的查询结果按您指定的变量分组。您还可以根据您的变量添加某种类型的状态,然后将其按附加列汇总,并选择不在汇总中显示最后一列。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-21
      • 2023-03-02
      • 1970-01-01
      • 2010-11-28
      • 1970-01-01
      相关资源
      最近更新 更多