无法在多个公用表表达式中绑定标识符
Posted
技术标签:
【中文标题】无法在多个公用表表达式中绑定标识符【英文标题】:Identifier could not be bound in multiple common table expressions 【发布时间】:2020-09-15 19:47:54 【问题描述】:我正在使用“使用 SQL 和 Excel 进行数据分析”一书中的 SQLBook 数据库来显示总发货天数高于平均发货天数的州的平均发货天数。我正在使用 2 个公用表表达式:
WITH orderDetails (days, state)
AS(
SELECT DATEDIFF(day, o.OrderDate, ol.ShipDate), o.State
FROM SQLBook.dbo.Orders o
JOIN [SQLBook].dbo.OrderLines ol
ON ol.OrderId = o.OrderId
)
,
/* This finds the overall average shipping days */
AvgShipping (avgShip)
AS(
SELECT AVG(DATEDIFF(day, o.OrderDate, ol.ShipDate))
FROM SQLBook.dbo.Orders o
JOIN [SQLBook].dbo.OrderLines ol
ON ol.OrderId = o.OrderId
)
SELECT
state,
AVG(days) AS "Average days to ship"
FROM orderDetails
GROUP BY state
HAVING AVG(days) > AvgShipping.avgShip
ORDER BY state
问题是我不断收到“无法绑定多部分标识符“AvgShipping.avgShip””错误。请让我知道这个查询的问题出在哪里。
谢谢!
【问题讨论】:
【参考方案1】:您不会在任何地方从 AvgShpping 中进行选择。试试
WITH orderDetails (days, state)
AS(
SELECT DATEDIFF(day, o.OrderDate, ol.ShipDate), o.State
FROM SQLBook.dbo.Orders o
JOIN [SQLBook].dbo.OrderLines ol
ON ol.OrderId = o.OrderId
)
,
/* This finds the overall average shipping days */
AvgShipping (avgShip)
AS(
SELECT AVG(DATEDIFF(day, o.OrderDate, ol.ShipDate))
FROM SQLBook.dbo.Orders o
JOIN [SQLBook].dbo.OrderLines ol
ON ol.OrderId = o.OrderId
)
SELECT
state,
AVG(days) AS "Average days to ship"
FROM orderDetails
GROUP BY state
HAVING AVG(days) > (select avgShip from AvgShipping)
ORDER BY state
【讨论】:
【参考方案2】:您需要将AvgShipping
放在外部查询的from
子句中,这样您就可以使用它的列:
WITH ...
SELECT od.state, AVG(od.days) AS average_days_to_ship
FROM orderDetails od
CROSS JOIN AvgShipping s
GROUP BY od.state, s.avgShip
HAVING AVG(od.days) > s.avgShip
ORDER BY od.state
但我认为使用窗口函数可以更有效地完成这项任务:
select *
from (
select state,
avg(datediff(day, o.orderdate, ol.shipdate)) as avg_days_state,
1.0 * sum(sum(datediff(day, o.orderdate, ol.shipdate))) over()
/ sum(count(*)) over() as avg_days_overall
from sqlbook.dbo.orders o
inner join sqlbook.dbo.orderlines ol on ol.OrderId = o.OrderId
group by state
) t
where avg_days_state > avg_days_overall
我们可以通过避免聚合并改用distinct
来稍微简化逻辑:
select distinct state, avg_days_state, avg_days_overall
from (
select state,
avg(datediff(day, o.orderdate, ol.shipdate)) over(partition by o.state) as avg_days_state,
avg(datediff(day, o.orderdate, ol.shipdate)) over() as avg_days_overall
from sqlbook.dbo.orders o
inner join sqlbook.dbo.orderlines ol on ol.OrderId = o.OrderId
) t
where avg_days_state > avg_days_overall
【讨论】:
以上是关于无法在多个公用表表达式中绑定标识符的主要内容,如果未能解决你的问题,请参考以下文章