获得相同结果集的其他方法有哪些
我正在使用4张桌子
SELECT * FROM Terminal
SELECT * FROM Customer
SELECT * FROM Contract
SELECT * FROM ExternalTable
这4个表格中的数据如下:
我写的查询是
select ex.TerminalName,ex.CustomerName from ExternalTable ex
except
select t.TerminalName,ct.CustomerName from [Contract] c
inner join Terminal t on t.TerminalID=c.TerminalID
inner join Customer ct on ct.CustomerId=c.CustomerId
获得以下结果
所以只是想知道获得同样结果的其他方法是什么
答案 0 :(得分:1)
我并不是你想要的,但是这是另一种编写应该产生相同结果的查询的方法:
SELECT
ex.TerminalName,
ex.CustomerName
FROM
ExternalTable ex
WHERE
NOT EXISTS( SELECT
NULL
FROM
[Contract] c
INNER JOIN
Terminal t on t.TerminalID = c.TerminalID
INNER JOIN
Customer ct on ct.CustomerId = c.CustomerId
WHERE
t.TerminalName = ex.TerminalName
AND
ex.CustomerName = ct.CustomerName
)
答案 1 :(得分:1)
这应该是等同的:
select ex.TerminalName,ex.CustomerName
from
ExternalTable ex
left outer join
(
[Contract] c
inner join Terminal t
on t.TerminalID=c.TerminalID
inner join Customer ct
on ct.CustomerId=c.CustomerId
)
on ex.TerminalName = t.TerminalName and ex.CustomerName = ct.CustomerName
where t.TerminalName is null and ct.CustomerName is null
您应该注意except
返回不同的结果,并且严格相同,我需要指定select distinct
。
答案 2 :(得分:1)
这是一个自包含的示例,显示了两个替代方案。 一个使用NOT IN,另一个使用LEFT OUTER JOIN,但它们应该是等效的。
--set up temp tables with dummy data to replicate the issue
declare @Terminal table(terminalid int,terminalname nvarchar(100));
insert into @Terminal select 1,'Terminal1' union select 2,'Terminal2'
declare @Customer table(customerid int,customername nvarchar(100));
insert into @Customer select 1,'Customer1' union select 2,'Customer2';
declare @Contract table(contractid int,terminalid int,customerid int,contractname nvarchar(100));
insert into @Contract select 1,1,1,'Contract1';
declare @ExternalTable table(externalid int,terminalname nvarchar(100),customername nvarchar(100),contractname nvarchar(100));
insert into @ExternalTable select 1,'Terminal1','Customer1','Contract1' union select 2,'Terminal2','Customer1','Contract1'
--SELECT * FROM @Terminal
--SELECT * FROM @Customer
--SELECT * FROM @Contract
--SELECT * FROM @ExternalTable
--goal: show records that are in the external table, but are not fully linked in the other tables
--original
select ex.TerminalName,ex.CustomerName from @ExternalTable ex
except
select t.TerminalName,ct.CustomerName from @Contract c
inner join @Terminal t on t.TerminalID=c.TerminalID
inner join @Customer ct on ct.CustomerId=c.CustomerId
--revised (left outer join method)
select et.TerminalName,et.CustomerName
from
@ExternalTable et
left join (
select ex.externalid
from
@Contract c
inner join @Terminal t on t.TerminalID=c.TerminalID
inner join @Customer ct on ct.CustomerId=c.CustomerId
inner join @ExternalTable ex on ex.terminalname = t.terminalname and ex.customername = ct.customername
) excludes on excludes.externalid = et.externalid
where excludes.externalid is null
--revised ("not in" method)
select et.TerminalName,et.CustomerName
from
@ExternalTable et
where et.externalid not in(
select ex.externalid
from
@Contract c
inner join @Terminal t on t.TerminalID=c.TerminalID
inner join @Customer ct on ct.CustomerId=c.CustomerId
inner join @ExternalTable ex on ex.terminalname = t.terminalname and ex.customername = ct.customername
)