Identifier could not be bound in multiple common table expressions

…衆ロ難τιáo~ 提交于 2021-01-29 09:44:42

问题


I'm using the SQLBook database from the Data Analysis Using SQL and Excel book to display the average days to ship for states that have higher than average overall shipping days. I'm using 2 common table expressions:

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

The problem is I keep getting a "The multi-part identifier "AvgShipping.avgShip" could not be bound" error. Please let me know where the problem with this query is.

Thanks!


回答1:


You're not selecting from AvgShpping anywhere. Try

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:


You would need to put AvgShipping in the from clause of the outer query so you can then use its column:

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

But I think this task can be done more efficiently with window functions:

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

We can simplify the logic a little by avoiding aggregation and using distinct instead:

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


来源:https://stackoverflow.com/questions/63908896/identifier-could-not-be-bound-in-multiple-common-table-expressions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!