加入子查询不起作用?

时间:2009-10-09 20:35:41

标签: sql-server sql-server-2005 tsql

我应该能够从子查询中引用join子句中的表,不应该吗?

但是以下查询给我的错误说他们无法绑定:

select *
from call c
JOIN call_task ct ON c.call_no=ct.call_no AND ct.calltask_no = (select min(ict.calltask_no) FROM call_task ict WHERE ict.call_no=c.call_no)
JOIN business b ON c.service_business_id=b.business_id
JOIN item i ON ct.item_id=i.item_id
JOIN    (   select top 1 * 
            FROM contract_line icl
            WHERE   icl.item_id = i.item_id 
                AND icl.location_no = c.service_location_no 
                AND icl.business_id = b.business_id
            ORDER BY icl.cancel_date asc
        ) cl ON i.item_id=cl.item_id 
             AND cl.location_no=c.service_location_no 
             AND cl.business_id=b.business_id
JOIN [contract] co ON cl.cont_no=co.cont_no
JOIN business_location bl ON bl.business_id=c.service_business_id AND bl.location_no=c.service_location_no
WHERE b.bus_code='INGRAM04'
AND ct.cont_no is null
AND call_sts NOT IN ('BB', 'BI', 'CA', 'CL', 'IP')
--AND cl.end_date > c.entry_date
ORDER BY c.create_time

错误是: 消息4104,级别16,状态1,第1行 无法绑定多部分标识符“i.item_id”。 消息4104,级别16,状态1,第1行 无法绑定多部分标识符“c.service_location_no”。 消息4104,级别16,状态1,第1行 无法绑定多部分标识符“b.business_id”。

我不明白为什么我会收到这些错误,并且无法想到任何解决方法。 contract_line上的item_no可以在合同上出现多次,如果它已被取消并且例如创建了新行。在这些情况下,我需要忽略已取消的行并拉出当前行。通过cancel_date执行子查询和排序首先拉出空值,以便完成我想要的...但是这个奇怪的绑定错误让我搞砸了。我知道我之前使用过这种技术,所以现在我很困惑......

3 个答案:

答案 0 :(得分:5)

您无法在JOIN中使用相关子查询。请改用APPLY。使用KM的例子:

declare @table table (t int);
select     t1.t     
from @table t1    
cross apply (select t2.t from @table t2 where t1.t=t2.t) as dt

答案 1 :(得分:1)

我认为这个错误来自于您正在使用cl进行别名的选择,然后尝试加入

WHERE   icl.item_id = i.item_id 
AND icl.location_no = c.service_location_no 
AND icl.business_id = b.business_id

你不能在那里引用“i”和“c”和“b”。

答案 2 :(得分:0)

这不是子查询,而是派生表(或者一些称为内联视图)。这是一个简单的查询来显示同样的问题:

declare @table table (t int)
select 
    t1.t 
    from @table t1
    inner join (select t2.t from @table t2 where t1.t=t2.t) dt on 1=1

Msg 4104, Level 16, State 1, Line 2
The multi-part identifier "t1.t" could not be bound.

( )之间的所有内容都与外部查询隔离。

这是一个有效的子查询:

select 
    t1.t 
    from @table t1
    WHERE exists (select * from @Table t2 where t1.t=t2.t)

输出:

t
-----------

(0 row(s) affected)