Mssql 错误:列 'dbo.History.Email' 在 select 列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中

Mssql err: Column 'dbo.History.Email' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

执行此 MSSQL 语句时,它强制我在分组字段中添加 CASE WHEN 字段 History.Email,但是我只需要在日期字段上分组。 知道如何解决这个问题吗? (sql 2008)

SELECT     TOP (100) 

convert(varchar, VisitDate, 111) as Date, 
SUM(AmountLoaded) AS Loaded, 

CASE when History.Email is null then
              SUM(AmountCash) 
       else   SUM(AmountToPay)  
       end    AS Total,
                    
CASE when History.Email is null then
              0
       else   SUM(AmountToPay)
       end    AS App,
                                                         
SUM(AmountToPay) AS Consumed
                       
FROM       dbo.History
GROUP BY   convert(varchar, VisitDate, 111)
order by 1 desc

执行条件聚合时,您需要将 整个 CASE 表达式放入聚合中,而不仅仅是要聚合的表达式:

SELECT TOP (100)
       CONVERT(varchar(10), H.VisitDate, 111) AS [Date], --Always specify a length/precision/scale for your data types
       SUM(H.AmountLoaded) AS Loaded,
       SUM(CASE WHEN H.Email IS NULL THEN H.AmountCash ELSE H.AmountToPay END) AS Total,
       SUM(CASE WHEN H..Email IS NULL THEN 0 ELSE H.AmountToPay END) AS App,
       SUM(H.AmountToPay) AS Consumed
FROM dbo.History H
GROUP BY CONVERT(varchar(10), H.VisitDate, 111) --Always specify a length/precision/scale for your data types
ORDER BY [Date] DESC; --Be specific, don't use ordinal positions

另外请注意,我建议 不要 将查询中的列 VisitDate 转换为 varchar。如果您想显示 特定格式的数据,那么这是您的表示层要做的事情,而不是 RDBMS。幸运的是,由于样式 111yyyy/MM/dd,因此数据的顺序不受影响。但是,如果您只想截断值的时间部分,请将其转换为 date,以便该值继续保持强类型。

根据定义,任何非聚合字段都应位于 group by 子句中。您可以将其写为:

SELECT     TOP (100) 
convert(varchar, VisitDate, 111) as Date, 
SUM(AmountLoaded) AS Loaded, 
SUM(CASE when History.Email is null 
         then AmountCash 
         else AmountToPay end)    AS Total,
SUM(CASE when History.Email is null 
         then 0
         else AmountToPay
         end)    AS App,
SUM(AmountToPay) AS Consumed
FROM       dbo.History
GROUP BY   convert(varchar, VisitDate, 111)
order by 1 desc