我试图找到一个特定的SQL语句来替换旧的SQL查询。总而言之,我尝试仅在满足条件的情况下进行左连接。这是我的测试环境:
create table Mst
(
Id bigint not null primary key clustered,
Firstname nvarchar(200) not null,
Lastname nvarchar(200) not null
);
create table Dtl
(
Id bigint not null primary key clustered,
MstId bigint not null references Mst(Id),
DetailDescr nvarchar(500) not null
);
我用一些数据填充表格:
declare @i as bigint = 0;
while @i < 999
begin
insert into Mst values (@i, N'Name ' + Str(@i), N'Lastname ' + Str(@i));
if (@i % 10 = 0)
insert into Dtl values (@i*5+0, @i, N'Description 1 for ' + Str(@i));
if (@i % 2 = 0)
insert into Dtl values (@i*5+1, @i, N'Description 2 for ' + Str(@i));
if (@i % 3 = 0)
insert into Dtl values (@i*5+2, @i, N'Description 3 for ' + Str(@i));
set @i = @i + 1;
end;
左联接的通常方法是这样:
select m.Id, m.Firstname, m.Lastname, d.DetailDescr
From Mst m left join Dtl d
on m.id = d.MstId;
此查询返回1266行。但是在我尝试迁移的旧应用程序中,select和from部分仍然是预定义的:
select m.Id, m.Firstname, m.Lastname, d.DetailDescr
From Mst m, Dtl d
旧的条件定义(在单独的软件模块中)不再可用的LEFT JOIN:
where m.id *= d.MstId
因此,我们必须迁移该方法,并尽可能尝试仅修改where条件。对于内部联接,where条件很容易定义:
where m.id = d.MstId
但是我需要左连接,仅通过修改where条件就找不到方法。但是只重写where条件是该特殊应用程序中的最佳方法。
预先感谢您的想法。
从前,SQL不支持外部联接语法。这是一个古老的世界,电话通过电线连接到墙上,欧洲的每个县都有自己的货币,大多数美国人在电视上观看三到四个主要网络之一。
当时,Microsoft甚至没有真正的数据库。但是Sybase在WHERE
子句*=
中提供了一个外部联接运算符,Microsoft最终将其改编为SQL Server。 Microsoft SQL Server通过SQL Server 2008支持此操作。因此,在WHERE
子句中,没有受支持的SQL Server版本支持外部联接。
很高兴,现在存在一种更好的标准语法(至少我们会灰心,认为随着时间的推移事情不会变得更好)。 FROM
子句中的“逗号运算符”被保留为其原始定义-CROSS JOIN
。 CROSS JOIN
过滤掉不匹配项。例如,如果Dtl
没有行,则CROSS JOIN
不返回行。
即,没有方法可以在WHERE
子句中做您想做的一般事情。有一些查询可以复制外部JOIN
,但它们需要对查询进行更多的操作。但是,还有一个不错的选择,那就是使用正确的现代语法编写查询。