Sql 捕获联接表达式中的所有记录
我有一个非常简单的问题(我认为很简单,但我仍在努力!)。我有一桌汽车。我有另一张汽车分类表。我想一个接一个地参加,以获得这辆车的等级 cars表很简单,有模型和品牌。类表还具有一个模型、一个make和一个类类型。当我想将同一品牌的汽车组合在一起,而不考虑它们的型号时,问题就出现了 例如,我有两辆车:Sql 捕获联接表达式中的所有记录,sql,tsql,join,sql-server-2008-r2,left-join,Sql,Tsql,Join,Sql Server 2008 R2,Left Join,我有一个非常简单的问题(我认为很简单,但我仍在努力!)。我有一桌汽车。我有另一张汽车分类表。我想一个接一个地参加,以获得这辆车的等级 cars表很简单,有模型和品牌。类表还具有一个模型、一个make和一个类类型。当我想将同一品牌的汽车组合在一起,而不考虑它们的型号时,问题就出现了 例如,我有两辆车: id vehiclemake vehiclemodel 1 AUDI R8 2 AUDI Quattro 我有两门课: id vehicle
id vehiclemake vehiclemodel
1 AUDI R8
2 AUDI Quattro
我有两门课:
id vehiclemake vehiclemodel classtype
1 AUDI R8 A
2 AUDI NULL B
奥迪R8将匹配A类车型。我希望所有其他奥迪车型,无论其车型如何,都匹配B类车型
我这里有一些示例代码,你可以玩一玩
create table #vehicle(id int, vehiclemake varchar(10), vehiclemodel varchar(10))
create table #vehicleclass(id int, vehiclemake varchar(10), vehiclemodel varchar(10), classtype varchar(1))
insert into #vehicle values(1, 'AUDI', 'R8')
insert into #vehicle values(2, 'AUDI', 'Quattro')
insert into #vehicleclass values(1, 'AUDI', 'R8', 'A')
insert into #vehicleclass values(2, 'AUDI', null, 'B')
select
*
from
#vehicle v
left join #vehicleclass vc on
(v.vehiclemake = vc.vehiclemake and v.vehiclemodel = vc.vehiclemodel)
drop table #vehicle
drop table #vehicleclass
上面的语句没有将Quattro记录连接到B类记录在车辆模型
的连接上使用a,这样当车辆类
表上的模型为空时,车辆将与其自己的模型匹配
[编辑]:阅读用户评论后,尝试以下操作:
SELECT *
FROM #vehicle v
INNER JOIN #vehicleclass vc
ON v.vehiclemake = vc.vehiclemake
AND v.vehiclemodel = vc.vehiclemodel
UNION
SELECT *
FROM #vehicle v
INNER JOIN #vehicleclass vc
ON v.vehiclemake = vc.vehiclemake
AND vc.vehiclemodel IS NULL
WHERE NOT EXISTS(SELECT 1
FROM #vehicleclass vc2
where vc2.vehiclemake = v.vehiclemake
and vc2.vehiclemodel = v.vehiclemodel);
也许这就是你想要的:
SELECT *
FROM #vehicle v
JOIN #vehicleclass vc ON v.vehiclemake = vc.vehiclemake
AND ( v.vehiclemodel = vc.vehiclemodel
OR ( vc.vehiclemodel IS NULL
AND v.vehiclemodel NOT IN (
SELECT vehiclemodel
FROM #vehicleclass
WHERE vehiclemodel IS NOT NULL )
)
)
输出:
id vehiclemake vehiclemodel id vehiclemake vehiclemodel classtype
1 AUDI R8 1 AUDI R8 A
2 AUDI Quattro 2 AUDI NULL B
输出:
id vehiclemake vehiclemodel id vehiclemake vehiclemodel classtype
1 AUDI R8 1 AUDI R8 A
2 AUDI Quattro 2 AUDI NULL B
我倾向于在这里使用
UNION ALL
,因为您确实有两个需求
SELECT *
FROM #Vehicle AS v
INNER JOIN #vehicleclass AS vc
ON vc.VehicleMake = v.VehicleMake
AND vc.VehicleModel = v.VehicleModel
UNION ALL
SELECT *
FROM #Vehicle AS v
INNER JOIN #vehicleclass AS vc
ON vc.VehicleMake = v.VehicleMake
AND vc.VehicleModel IS NULL
WHERE NOT EXISTS
( SELECT 1
FROM #vehicleclass AS vc2
WHERE vc2.VehicleMake = v.VehicleMake
AND vc2.VehicleModel = v.VehicleModel
);
要在没有工会的情况下执行此操作,您可以使用:
SELECT *
FROM #Vehicle AS v
CROSS APPLY
( SELECT TOP 1 *
FROM #vehicleclass AS vc
WHERE vc.VehicleMake = v.VehicleMake
ORDER BY CASE WHEN vc.VehicleModel = v.VehicleModel THEN 0 ELSE 1 END
) AS vc;
它将取决于您在每个表上拥有的索引,以确定哪些索引的性能更好。由于没有索引,后者有更好的执行计划,因为它只需要两次扫描,但如果我向每个表添加索引:
CREATE NONCLUSTERED INDEX #IX_Vehicle__VehicleMake_VehicleClass ON #Vehicle (VehicleMake, VehicleModel) ;
CREATE NONCLUSTERED INDEX #IX_VehicleClass__VehicleMake_VehicleClass ON #Vehicle (VehicleMake, VehicleModel);
然后前者变得更有效,因为它能够更好地利用索引搜索。在这种情况下,您希望得到什么输出?SQLFiddle链接:在本例中,结果应为:1奥迪R8 1奥迪R8 A 2奥迪Quattro 2奥迪空BIs在车型为空的表vehicleclass中,每辆车最多有1条记录?是,每个车型/车辆只生成一条记录,其中model/null为全部,但它为R8带回了两条记录,其中它与车型匹配,且车型为null。对于R8记录,它应该只在一次Hello!我想我们可能会赢!这些
Id
值在表之间匹配只是巧合。该列不是要匹配的有效列。
CREATE NONCLUSTERED INDEX #IX_Vehicle__VehicleMake_VehicleClass ON #Vehicle (VehicleMake, VehicleModel) ;
CREATE NONCLUSTERED INDEX #IX_VehicleClass__VehicleMake_VehicleClass ON #Vehicle (VehicleMake, VehicleModel);