【问题标题】:SQL join two tables matching only 1 row to 1 rowSQL join 两个表只匹配 1 行到 1 行
【发布时间】:2015-09-11 18:27:56
【问题描述】:

我正在寻找......没有更好的词,“独占连接”。我只希望右侧的 1 行与左侧的一行匹配,并且不能连接到前一行。解决方案应该适用于 MS SQL 2012。

示例:我有两个表 A 和 B,每个表有 10 行。 A1 行匹配 B3 和 B5,A3 行匹配 B3 和 B5。结果集应包括 2 行:A1 连接到 B3(因为它是右侧的第一个匹配),以及 A3 连接到 B5(因为它是右侧的第一个尚未使用的匹配)。

显然,我试图避免使用游标。也许递归 CTE 是解决此问题的唯一其他方法?

【问题讨论】:

  • 没有显示表结构和到目前为止您尝试过的查询..很难回答。
  • 为了帮助您,我们至少需要表的架构和两个表之间的 FK 关系。
  • 查看左右连接的工作原理。
  • 我认为cross join 可以做到这一点,无需加入专栏。看我的回答。

标签: sql sql-server select join


【解决方案1】:

执行此操作的一种方法是将row_number 调用应用到加入列,然后在加入时在其上添加条件:

SELECT a.*, b.*
FROM   (SELECT *, ROW_NUMBER() OVER (PARTITION BY join_col ORDER BY 1) rn
        FROM   table_a) a
JOIN   (SELECT *, ROW_NUMBER() OVER (PARTITION BY join_col ORDER BY 1) rn
        FROM   table_b) b ON a.join_col = b.join_col AND a.rn = b.rn

【讨论】:

  • 在阅读问题时正在考虑这个确切的解决方案。肯定有点奇怪,但肯定在可能性范围内。
  • 这正是我想要的。谢谢。
【解决方案2】:

请参阅下面的脚本。 CTE 和 cursor 不是我理解的淘汰赛要求......无论如何,我希望它会导致你的答案。

Without a identifier to join on(正如您的问题中未提供的那样,我认为需要cross join,而partition by 可以解决问题。

类似这样的:

create table #t (a nvarchar(2),rna int, b nvarchar(2), rnb int)

insert into #t select * from
(select a 
    ,row_number() over (partition by a order by a) rna
    ,b
    ,row_number() over (partition by b order by b) rnb
from table_a
cross join
table_b     
) as x
where rnb=1

select a, b from #t 
drop table #t

这里有一个创建表格的脚本: 创建表 table_a(一个 nvarchar(2)) 插入 table_a 值 ('A1'),('A3');

create table table_b (b nvarchar(2)) 
insert into table_b values ('B3'),('B5');

【讨论】:

    猜你喜欢
    • 2018-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 2016-08-07
    相关资源
    最近更新 更多