【问题标题】:Receiving 'Aggregate cannot appear in an ON clause' Error收到“聚合不能出现在 ON 子句中”错误
【发布时间】:2017-03-21 14:21:37
【问题描述】:

我收到此错误:聚合不能出现在 ON 子句中,除非它位于 HAVING 子句或选择列表中包含的子查询中,并且正在聚合的列是外部引用。

我不知道如何解决这个问题,请帮忙。

set datefirst 2

select [Table 2].[Active_Headcount]
    , DATEADD(DD, 7 - (DATEPART(DW, MIN([Table 1].[Term Date]))), MIN([Table 1].[Term Date])) as EndOfWeek
    , COUNT(*) as TermsPerWeek
from [Table 1]
left join [Table 2]
    on (DATEADD(DD, 7 - (DATEPART(DW, MIN([Table 1].[Term Date]))), MIN([Table 1].[Term Date]))) = [Table 2].[WeekDate]
where [Table 1].[Term Date] not like 'null'
    and (
        [Table 1].[Term Date] like '%2016%'
        or [Table 1].[Term Date] like '%2017%'
        )
group by DATEPART(WEEK, [Table 1].[Term Date])
    , [Table 2].[Active_Headcount]
order by EndOfWeek asc;

【问题讨论】:

  • (1) 用您正在使用的数据库标记您的问题。 (2) 描述你想做什么。语法错误的查询并不总能传达编写者的意图。
  • 我正在汇总日期 [Term Date] 'as EndOfWeek',在星期一结束并希望加入表 2(日期也在星期一结束)。我遇到的问题是,我需要根据“EndOfWeek”而不是 [Term Date] 加入。
  • 请编辑添加一些示例数据预期结果
  • 您能否编辑您的查询以指明哪些列来自哪个表? (例如,将Active_Headcount 更改为[Table 1].Active_Headcount。)谢谢!
  • @BenGribaudo 我做了编辑

标签: sql sql-server-2012


【解决方案1】:

基本上就是它所说的。您不能在 JOIN 条件的 ON 子句中执行聚合操作。您需要使用APPLY 运算符。

另外,我会从您的代码中假设 [HeadcountByWeek] 是您的 "table 2"

set datefirst 2

select Active_Headcount
    , DATEADD(DD, 7 - (DATEPART(DW, MIN([Term Date]))), MIN([Term Date])) as EndOfWeek
    , COUNT(*) as TermsPerWeek
from table t1
outer apply (
    select * 
    from [HeadcountByWeek] t2 
    where (DATEADD(DD, 7 - (DATEPART(DW, MIN(t1.[Term Date]))), MIN(t1.[Term Date]))) = t2.[WeekDate] ) t2
where t1.[Term Date] not like 'null'
    and (
        t1.[Term Date] like '%2016%'
        or t1.[Term Date] like '%2017%'
        )
group by DATEPART(WEEK, t1.[Term Date])
    , t1.[Active_Headcount]
order by EndOfWeek asc;

【讨论】:

  • [Term Date] 来自表 1,[Active_Headcount] 来自表 2
  • 我调整了代码并收到:APPLY右侧的聚合无法引用左侧的列。
【解决方案2】:

我会这样做:

set datefirst 2;

With cte(Active_Headcount, EndOfWeek, TermsPerWeek)
as (select Active_Headcount
, DATEADD(DD, 7 - (DATEPART(DW, MIN([Term Date]))), MIN([Term Date])) as EndOfWeek
, COUNT(*) as TermsPerWeek
from table 1
)
select * from cte
left join table 2
on cte.EndOfWeek = [HeadcountByWeek].[WeekDate]
where [Term Date] not like 'null'
and (
    [Term Date] like '%2016%'
    or [Term Date] like '%2017%'
    )
 group by DATEPART(WEEK, [Term Date])
, [Active_Headcount]
order by EndOfWeek asc;

这不会开箱即用,因为我不知道哪些列来自哪个表。

主要思想是将查询分解为 CTE,然后在下面的联接中使用该 cte 中的列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-16
    • 1970-01-01
    • 1970-01-01
    • 2014-12-26
    相关资源
    最近更新 更多