有人可以帮我弄清楚最好的方法是怎样做的?
我有车的人员名单.我需要执行一个查询,该查询将返回具有某种类型的汽车且同时没有其他类型的人.
这是我的例子:
ID Name CarType ----------- ---------- ---------- 1 John MINI VAN 1 John SUV 2 Mary SUV 2 Mary SEDAN 3 Paul SPORT 3 Paul TRUCK 4 Joe SUV 4 Joe MINI VAN
例如,我想只显示有SUV且没有MINI VAN的人.如果我们尝试子句CarType IN('SUV')而不是IN('MINI VAN'),这将不起作用,因为第二个语句被忽略.
为了返回具有类型但同时没有其他类型的人,我尝试了以下方法:
使用IN子句创建一个临时表,比方说@Contains
使用NOT IN子句创建一个临时表,假设是@DoesNotContain
使用@Contains连接表,这将执行IN子句
在where子句中,查找不在@DoesNotContain表中的ID.
我正在使用的查询是这样的:
--This is the IN Clause declare @Contains table( ID int not null ) --This is the NOT IN Clause declare @DoesNotContains table( ID int not null ) --Select IN insert into @Contains SELECT ID from @temp where CarType = 'SUV' --Select NOT IN insert into @DoesNotContains SELECT ID from @temp where CarType = 'MINI VAN' SELECT a.ID, Name FROM @temp a INNER JOIN @Contains b on b.ID = a.ID WHERE a.ID NOT IN (SELECT ID FROM @DoesNotContains) Group by a.ID, Name
这将归还Mary,因为她有一辆SUV,但没有MINI VAN.
这是我的问题:
在没有临时表的情况下,是否可以在查询中执行此IN和NOT IN?SQL中有新的东西吗?(抱歉,我上次使用SQL时是SQL 2005)
我们应该使用临时表吗?
如果这是要走的路,我应该使用IN而不是IN而不是JOIN吗?
如何用JOIN替换NOT IN子句?
谢谢你们!
编辑
我刚刚测试了解决方案,但不幸的是我没有说明我需要组合的cartypes.我的错 :(
例如,如果我希望所有用户都拥有SUV和MINI VAN而不是TRUCK而不是SEDAN.在这种情况下,只返回约翰.
这通常使用标准SQL中的单个查询来完成,使用NOT EXISTS
:
SELECT * FROM mytable AS t1 WHERE CarType = 'SUV' AND NOT EXISTS (SELECT * FROM mytable AS t2 WHERE t1.Name = t2.Name AND t2.CarType = 'MINI VAN')
上面的查询将选择所有人CarType = 'SUV'
,但没有CarType = 'MINI VAN'
.
这是一种方式
SELECT Id, Name FROM Cars WHERE CarType = 'SUV' EXCEPT SELECT Id, Name FROM Cars WHERE CarType = 'MINI VAN'
或其他
SELECT Id, Name FROM Cars WHERE CarType IN ('SUV', 'MINI VAN') GROUP BY Id, Name HAVING MIN(CarType) = 'SUV'
或者是更通用的版本,可以满足评论中的不同要求.
SELECT Id, NAME FROM Cars WHERE CarType IN ( 'SUV', 'MINI VAN', 'TRUCK') GROUP BY Id, NAME HAVING COUNT(DISTINCT CASE WHEN CarType IN ( 'SUV', 'MINI VAN' ) THEN CarType END) = 2 AND COUNT(DISTINCT CASE WHEN CarType IN ( 'TRUCK' ) THEN CarType END) = 0