别名在GROUP BY中不可用

时间:2017-12-11 12:06:14

标签: sql-server tsql group-by alias

我必须对BaseIncidencia列进行分组(对值进行求和),但它不可用。如SQL Server AS statement aliased column within WHERE statement中所述,这很简单,但我没有要引用的列名。只有别名。

BEGIN
SELECT @Artigo AS Artigo, T1.Contrib AS ContribID, YEAR(T1.Data) AS Ano, T3.DescricaoMes, CAST(ROUND(SUM(T1.Debito/0.23),2) AS decimal(16,2)) BaseIncidencia,
       CAST(ROUND(SUM(T1.Debito),2) AS decimal(16,2)) AS IVA, (CASE WHEN T5.Valid = 'True' THEN 'VALIDO' WHEN T5.Name = '---' THEN 'INEXISTENTE' ELSE 'INVALIDO' END) AS 'ValidadeNIF'
FROM  
#CONTAS_INI AS T1  
LEFT JOIN  
db.dbo.VatCheck T5 
ON T1.ContribuinteID = T5.VatNumber 
LEFT JOIN
#Meses AS T3
ON MONTH(T1.Data) = T3.Mes
GROUP BY T1.CntID, T1.ContribuinteID, YEAR(T1.Data), (CASE WHEN T5.Valid = 'True' THEN 'VALIDO' 
         WHEN T5.Name = '---' THEN 'INEXISTENTE' ELSE 'INVALIDO' END), T3.DescricaoMes
ORDER BY (CASE WHEN T5.Valid = 'True' THEN 'VALIDO' WHEN T5.Name = '---' THEN 'INEXISTENTE' ELSE 'INVALIDO' END), T1.ContribuinteID
END

我尝试更换以下行:

GROUP BY T1.CntID, T1.ContribuinteID, YEAR(T1.Data), (CASE WHEN T5.Valid = 'True' THEN 'VALIDO' 

使用:

GROUP BY T1.CntID, T1.ContribuinteID, YEAR(T1.Data), CAST(ROUND(SUM(T1.Debito/0.23),2) AS decimal(16,2)), (CASE WHEN T5.Valid = 'True' THEN 'VALIDO'

仅获取Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause.错误。

所以我的问题是,为什么我不能在GROUP BY中包含BaseIncidencia别名?什么是解决方法?

3 个答案:

答案 0 :(得分:2)

实现SQL就好像按以下顺序执行查询一样:

  1. FROM clause
  2. WHERE子句
  3. GROUP BY子句
  4. HAVING条款
  5. SELECT条款
  6. ORDER BY子句
  7. 对于大多数关系数据库系统,此顺序说明了哪些名称(列或别名)有效,因为它们必须在上一步中引入。

    因此,在SQL Server中,您无法在SELECT子句中定义的GROUP BY子句中使用术语,因为GROUP BY在SELECT子句之前执行。

答案 1 :(得分:0)

您不能按表达式进行分组,因为它是一个聚合。 group by values用于确定聚合操作的级别。

作为一个简单的例子:

Select Count(*), 
       Object_id
From sys.columns
Group by Object_id

这很容易理解。计算每个object_id的列记录数。

您要做的事情相当于

SELECT      COUNT( * ),
            object_id
  FROM      sys.columns
  GROUP BY  COUNT( * ),
            object_id

对于每个object_id的计数,给我每个object_id的计数。这没有意义。

您收到的错误消息:

Cannot use an aggregate or a subquery in an expression used for the group by list of a GROUP BY clause

告诉您不能通过聚合表达式进行分组。

答案 2 :(得分:0)

重新发布12月12日的评论作为答案。

您可能希望将原始SELECT ... FROM ...SELECT * FROM ( /*your original half*/ ) AS T一起包裹,然后留下GROUP ... ORDER ...部分。这样您就可以在SELECT部分中引用内部GROUP ... ORDER ...生成的任何别名。

但是,由于GROUP移动到不同的级别,您还必须将SUM之类的聚合移动到新级别。此外,您将无法直接访问自己的表格,因此您很可能必须将GROUP ... ORDER ...段中使用的表别名更改为T,并确保所有列均为{{} 1}}正在使用的部分是在内部GROUP ... ORDER ...中生成的。所有这一切都应该很容易处理。