对于简单表格,使用“left join”和“is null”替换“Not In”应该很容易。但是,就我而言,这并不那么简单。使用“左连接”替换特殊情况下的“不在”子句的SQL语句
这里是表A(项目,ReferenceID)
Item(primary key) ReferenceID
Chair 123
Desk 456
Sofa 789
Bed 111
这里是tableB的(STOREID,ReferenceID)
StoreID(primary key) ReferenceID(primary key)
00001 123
00001 456
00002 123
00002 456
00003 111
注:表B是表示被排除在哪些项目表哪个商店。 因此storeID = 00001具有除主席(参考ID = 123)和桌面(参考ID = 456)以外的所有项目。
给定一个StoreID = 00001,我怎么能写一个sql语句来达到这个目的。更具体地说,结果表应该是:
Item(primary key) ReferenceID
Sofa 789
Bed 111
使用“Not-in”方法,其工作正常但缓慢。
select * from tableA
where ReferenceID not in (select ReferenceID from tableB where storeID='00001'
现在我试图不使用“不在”子句,因为性能低下。 我尝试使用“左连接”,但它似乎并没有返回我想要的。
#1。
select * from tableA left join tableB
on tableA.referenceID = tableB.referenceID
where tableB.StoreID is null
,因为它TableB中
存在#2这种方法就可以排除(床,111)。尝试添加storeID来过滤结果。
select * from tableA left join tableB
on (tableA.referenceID = tableB.referenceID and StoreID='00001')
where tableB.StoreID is null
结果集与排除(bed,111)的#1中的方法相同。
问题:
什么是正确的SQL语句来达到这个目的?
只要性能比使用“不在”条款更好,我也可以接受其他不使用“左连接”的方法。
编辑:
我简化了实际的SQL语句和上面的助手更容易明白我想实现的情况,因为我想跳过额外的表和SQL语句并不重要。
根据以下评论,我认为现在很重要,因为#2方法似乎在上述简化情况下正常工作。因此,我必须再添加一张表来重现我所遇到的实际问题。
其实还有一张表。我加入tableA和tableC,然后离开join tableB。
表C(项目,itemDescrption)
Item(primary key) itemDescrption
Chair Very comfortable.
Desk broken
sofa large sofa (24*12)
bed double size
至于上面的方法#2,实际的说法是
select * from tableA
inner join tableC on tableA.item = tableC.item
left join tableB
on (tableA.referenceID = tableB.referenceID and StoreID='00001')
where tableB.StoreID is null
2号除了'床'怎么样? – JNevill
(1)如果商店不会遗漏任何商品,那么它不会出现在报告中。你需要一个有商店的桌子。 (2)像这样的语法操作几乎不是实现性能的好路径 –
因为我以为我生气了,所以我在我的盒子上创建了'tableA'和'tableB'并运行了第二个查询。它工作正常。 – JNevill