2011-04-26 73 views
1

當我做減法時,在我的查詢中出現錯誤。我正在使用MS SQL。我該如何在這個查詢中做一個減號?

SELECT PT.PcbId 
    FROM dbo.DeviceTrace DT 
    JOIN dbo.PcbTrace PT ON DT.CompId = '101125937' 
         AND DT.DeviceID = PT.DeviceID 

NOT IN (SELECT PB.PcbId 
      FROM dbo.DeviceTrace DT 
      JOIN dbo.PcbTrace PT ON DT.CompId = '101125937' 
           AND DT.DeviceID = PT.DeviceID 
      JOIN dbo.PanelBlockTrace PB ON PB.PcbID = PT.PcbID) 

請問您能糾正我嗎?

+1

你有什麼問題? – 2011-04-26 05:18:22

回答

2

我重新寫你的查詢爲:

SELECT PT.PcbId 
    FROM dbo.PcbTrace PT 
WHERE EXISTS (SELECT NULL 
       FROM dbo.DeviceTrace DT 
       WHERE DT.DeviceID = PT.DeviceID 
        AND DT.CompId = '101125937') 
    AND NOT EXISTS (SELECT NULL 
        FROM dbo.PANELBLOCKTRACE pbt 
        WHERE pbt.pcbid = PT.pcbid) 

...因爲你複製你的第一個加入這個NOT IN部分,但有根據您提供的信息PANELBLOCKTRACE和DEVICETRACE沒有關係。

+0

存在子句對性能不好,因爲它遍歷整個直到找到匹配的值。一個不存在的情況會更糟,因爲它必須遍歷整個表以確認一個值不存在。內部連接或左連接(使用空檢查)可以更好地使用索引.. – 2011-04-26 05:23:01

+1

@ M.R .:你錯了 - EXISTS退出第一場比賽,如果可以預期重複,這將成爲更好的選擇。在處理不可空列時,LEFT JOIN/IS NULL在MySQL上效率更高 - 請參閱:http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join -is-null-sql-server/vs:http:// explainextended。com/2009/09/18/not-in-vs-not-exists-vs-left-join-is-null-mysql/ – 2011-04-26 05:25:31

+0

@OMG小馬什麼意思SELECT NULL? – 2011-04-26 05:28:54

1

你當你說「不」來指定字段名 - 這樣的:

 

select PT.PcbId 
from dbo.DeviceTrace DT INNER Join dbo.PcbTrace PT 
on DT.CompId = '101125937' and DT.DeviceID = PT.DeviceID 

and [fieldName] not in 

(select PB.PcbId 
from dbo.DeviceTrace DT INNER Join dbo.PcbTrace PT 
on DT.CompId = '101125937' and DT.DeviceID = PT.DeviceID 
INNER Join dbo.PanelBlockTrace PB 
on 
PB.PcbID = PT.PcbID) 
 

或者,如果你想擁有它在一個單獨的where子句,那麼你需要:

 

select PT.PcbId 
from dbo.DeviceTrace DT INNER Join dbo.PcbTrace PT 
on DT.CompId = '101125937' and DT.DeviceID = PT.DeviceID 

where [fieldName] not in 

(select PB.PcbId 
from dbo.DeviceTrace DT INNER Join dbo.PcbTrace PT 
on DT.CompId = '101125937' and DT.DeviceID = PT.DeviceID 
INNER Join dbo.PanelBlockTrace PB 
on 
PB.PcbID = PT.PcbID) 
 

雖然,你應該使用 'LEFT JOIN' 比 '不',這會快很多..

+0

NOT IN部分中的JOIN是無關的。並且SQL Server上的LEFT JOIN/IS NULL不會更快:http://explainextended.com/2009/09/15/not-in-vs-not-exists-vs-left-join-is-null-sql-server/ – 2011-04-26 05:22:40

+0

@OMG小馬:我把它放在原處,不知道邏輯是什麼......但是,以面值爲例,你是對的:) – 2011-04-26 05:25:55

0

使用除了沒有NOT IN,如:

SELECT query1 

EXCEPT 

SELECT query2 
1

它從您的查詢看起來好像您要排除符合您的CompID過濾條件的PanelBlockTrace中的那些PcbID。

試試這個:

select PT.PcbId 
from dbo.DeviceTrace DT 
INNER Join dbo.PcbTrace PT on DT.CompId = '101125937' 
          and DT.DeviceID = PT.DeviceID 
LEFT JOIN dbo.PanelBlockTrace PB ON PB.PcbID = PT.PcbID  
WHERE PB.PcbID IS NULL 

我喜歡這個解決方案上面在WHERE PT.PcbId NOT IN,因爲它會要求一重擊的表,而不是2,一個NOT IN需要。

1

測試:

select PT.PcbId 
from dbo.DeviceTrace DT INNER Join dbo.PcbTrace PT 
on DT.CompId = '101125937' and DT.DeviceID = PT.DeviceID 
where PT.PcbId 
not in 

(select PB.PcbId 
from dbo.DeviceTrace DT INNER Join dbo.PcbTrace PT 
on DT.CompId = '101125937' and DT.DeviceID = PT.DeviceID 
INNER Join dbo.PanelBlockTrace PB 
on 
PB.PcbID = PT.PcbID) 
0

您查詢似乎罰款。

如果有問題,請更具體。

另外,低於此查詢等同於你:

SELECT PT.PcbId 
FROM dbo.DeviceTrace DT 
    JOIN dbo.PcbTrace PT ON DT.CompId = '101125937' 
         AND DT.DeviceID = PT.DeviceID 

EXCEPT 

SELECT PcbId 
FROM dbo.PanelBlockTrace 

它具有結構簡單,可以幫助你更容易發現問題。