2009-10-09 55 views
1

我應該能夠從子查詢的連接子句中引用表,不是嗎?加入子查詢無法正常工作?

但是,下面的查詢是給我的錯誤說,他們不能綁定:

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,行 多部分標識符「 i.item_id「無法綁定。 Msg 4104,Level 16,State 1,Line 1 無法綁定多部分標識符「c.service_location_no」。 消息4104,級別16,狀態1,行1 無法綁定多部分標識符「b.business_id」。

我不明白爲什麼我會收到這些錯誤,想不出任何方法。 contract_line上的item_no可以在合同上出現多次,如果它被取消並創建一個新行。在這些情況下,我需要忽略取消的線路並拉出當前線路。做子查詢和通過cancel_date進行排序會首先獲取空值,這樣就完成了我想要的操作......但是這個奇怪的綁定錯誤讓我感到困惑。我知道我之前,所以現在我很困惑已經使用這種技術...

回答

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

我花了一段時間來了解CROSS APPLY ...但是,沒有的伎倆。 (我仍然發誓雖然我已經完成了子查詢,但...) – CodeRedick

+0

JOIN和APPLY之間存在一些語義差異,因此您必須謹慎行事,但通常情況下,每當想要加入依賴於右側的集合時在左側設置的當前行上,應用就是要走的路。鑑於你有TOP和ORDER,必須在依賴於c和b別名的WHERE之後應用*,我認爲APPLY是合適的。 –

1

我相信從你與CL然後試圖加入對

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

可以走樣選擇未來的錯誤我在此引用「我」和「c」和「b」。

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) 

OUTPUT:

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

(0 row(s) affected)