2011-04-26 69 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 

它具有结构简单,可以帮助你更容易发现问题。