SQL:包含多个字段的Case语句

时间:2013-05-17 19:15:37

标签: sql group-by case

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

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 ....有意义吗?

4 个答案:

答案 0 :(得分:8)

没有聚合的查询分组(例如您的查询)仅对删除重复项有用。因此,您可以选择为select子句中的列添加聚合,这些列不在组中,或者使用查询来删除重复项。

以下代码删除了只在group by语句中有条件的所有列(DVPname,RVPname,AEname,Dealer)(只要它们不在group by中,它就会在select中出现错误)。它还将名称添加到组中,以便它可以在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 

答案 1 :(得分:1)

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

例如,你的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;

答案 2 :(得分:0)

如果您只想要条件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;

这将返回列的最小值。

答案 3 :(得分:0)

我知道两种方法: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) 

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