连接ON子句的聚合函数

5

我有一张数据表item_table,它长这样:

item   age
--------------    
1      1 
1      6 
2      2    

我有另一张名为price_table的表格,内容如下:

item    pricetype    price
--------------------------    
1       O             5
1       P             6
1       V             7
2       O             8
2       P             9
2       V             10

因此,我想要内连接上述两个表。
select *
from item_table i
inner join price_table p
on ...

有一些关于on的条件:
  1. 如果一个项目的平均年龄大于3,则执行:inner join price_table on pricetype = 'O' or pricetype = 'P'
  2. 否则,执行:inner join price_table on pricetype = 'O' or pricetype = 'P' or pricetype = 'V'
因此,on有其自身的条件。
我将查询写成了这样:
select i.item, i.type, p.pricetype, p.price
from item_table i
inner join price_table p on i.item = p.item 
    and (avg(i.age) >= 3 and p.pricetype in ('O', 'P'))
        or (avg(i.age) < 3 and p.pricetype in ('O', 'P', 'V'))

错误提示为:An aggregate cannot appear in an ON clause unless it is in a subquery contained in a HAVING clause or select list, and the column being aggregated is an outer reference. 由于其他条件依赖于 avg,因此无法将其移动到Having中。
您应该如何编写选择查询语句?
2个回答

6
select *
from (
    select item, avg(age) as AvgAge
    from item_table
    group by item
) ia
inner join price_table p on ia.item = p.item 
    and ((ia.AvgAge >= 3 and p.pricetype in ('O', 'P'))
        or (ia.AvgAge < 3 and p.pricetype in ('O', 'P', 'V')))

SQL Fiddle Example 1

这可以简化为:

select *
from (
    select item, avg(age) as AvgAge
    from item_table
    group by item
) ia
inner join price_table p on ia.item = p.item 
    and (p.pricetype in ('O', 'P')
        or (ia.AvgAge < 3 and p.pricetype = 'V'))

SQL Fiddle Example 2


1

你尝试将聚合放在子查询中吗?然后你就可以在JOIN子句中使用avg()值:

select i.item, i.type, p.pricetype, p.price
from
(
    select avg(i.age) age, i.item, i.type  -- not sure where type is coming from in your OP as it is not in the table you showed
    from item_table i
    group by i.item, i.type
)   i
inner join price_table p 
    on i.item = p.item 
    and ((i.age>= 3 and p.pricetype in ('O', 'P'))
        or (i.age < 3 and p.pricetype in ('O', 'P', 'V')))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接