我想知道是否有人遇到过这个问题的简洁解决方案。我正在尝试从几个表中选择数据,让记录逐行匹配。我基本上是在完全外连接之后,但是有一个关键的区别。如果我在一个表中连接的列中有四个特定值的行,而另一个表中有三个具有此值的行,我只希望连接前三个结果,并且第四个行为就好像有一直不配。
这样做的原因是创建一个对帐报告,确保在比较结果时不会多次计算交易。我可以通过使用一些分组和一些聚合函数来解决这个问题,但这隐藏了一些我想保留的细节。
下面是一个示例,显示我正在追求的事情,评论中的无效/伪代码说明了我如何将其视为工作:
declare @t1 table (id bigint identity(1,1) primary key clustered, foreignKeyId bigint, otherData nvarchar(10))
declare @t2 table (id bigint identity(1,1) primary key clustered, foreignKeyId bigint, moreData nvarchar(10))
insert @t1 select 1, '1.1.1'
union all select 1, '1.1.2'
union all select 1, '1.1.3'
union all select 3, '1.3.1'
union all select 3, '1.3.2'
union all select 3, '1.3.3'
union all select 4, '1.4.3'
insert @t2 select 1, '2.1.1'
union all select 1, '2.1.2'
union all select 1, '2.1.3'
union all select 2, '2.2.1'
union all select 3, '2.3.1'
union all select 3, '2.3.2'
union all select 5, '2.5.1'
union all select 5, '2.5.2'
--demo of the functionality i'm hoping to acheive
--
/*
select t1.id id1
, t2.id id2
, t1.foreignKeyId fk1
, t2.foreignKeyId fk2
, t1.otherData otherData
, t2.moreData moreData
from @t1 t1
full funky join @t2 t2
on t1.foreignKeyId = t2.foreignKeyId
order by t1.id, t2.id --we'd need an order by to ensure the match could be applied in a predictable manner
*/
--
declare @funkyjoin table (id1 bigint, id2 bigint, fk1 bigint, fk2 bigint, otherData nvarchar(10), moreData nvarchar(10))
declare @id1 bigint, @id2 bigint
insert @funkyjoin (id1, fk1, otherData)
select id, foreignKeyId, otherData from @t1
while exists(select 1 from @t2)
begin
select top 1 @id2 = id from @t2 order by id
set @id1 = null
select top 1 @id1 = id1
from @funkyjoin
where fk2 is null
and fk1 in (select foreignKeyId from @t2 where id = @id2)
if @id1 is null
begin
insert @funkyjoin (id2, fk2, moreData)
select id, foreignKeyId, moreData
from @t2
where id = @id2
end
else
begin
update @funkyjoin
set id2 = @id2
, fk2 = fk1 --since we're joining on this we can just match it
, moreData = (select moreData from @t2 where id = @id2)
where id1 = @id1
end
delete from @t2 where id = @id2 --since this is only an example let's not worry about keeping our source data
end
select *
from @funkyjoin
order by coalesce(id1, id2)
我之前在电子表格上发生过这种情况的时候写过类似的解决方案:http://officemacros.codeplex.com/#WorksheetMergeMacro
答案 0 :(得分:3)
如果我理解正确,这可能就是你所追求的:
select *
from (
select *,
row_number() over (partition by foreignKeyId order by id) as n
from @t1
) t1
full outer join (
select *,
row_number() over (partition by foreignKeyId order by id) as n
from @t2
) t2 on t1.foreignKeyId = t2.foreignKeyId and t1.n = t2.n
答案 1 :(得分:1)
使用行的最佳方法是添加伪行号(使用ROW_NUMBER)并将其包含在连接中。