严格按顺序将两个表连接在一起

时间:2019-07-19 01:03:50

标签: sql

如果我有两个表(t1,t2),每个表只有一列

t1      
letters  
a         
b         
c         

t2
nums
1
2
3

是否有可能将两者“连接”在一起,从而生成看起来像这样的两列结果集:

letters nums
a       1
b       2
c       3

解决方案要求:

  • 必须按指定顺序组合每个表的数据,以便能够 在加入之前对每个表的数据进行排序
  • 不使用任何功能(例如row_number)添加要连接的额外列

奖励积分:  -如果两个表的行计数不同,则最终结果集将是两个表的最大值的计数,并且“丢失”数据为null。

只是想知道在给定约束的情况下这是否可能。

2 个答案:

答案 0 :(得分:5)

您要使用row_number()。但是,SQL表表示无序集,因此您需要一列来指定顺序。

想法是:

select l.letter, n.number
from (select l.*, row_number() over (order by ?) as seqnum
      from letters l
     ) l join
     (select n.*, row_number() over (order by ?) as seqnum
      from numbers n
     ) n
     on l.seqnum = n.seqnum;

?用于指定顺序的列。

如果要在两个表中都包含所有行,请使用full join而不是内部联接。

EDTI:

row_number()是显而易见的解决方案,但是您可以使用相关的子查询(假定值是唯一的)来做到这一点:

select l.letter, n.number
from (select l.*, 
             (select count(*) from letters l2 where l2.letter <= l.letter) as seqnum
      from letters l
     ) l join
     (select n.*, 
             (select count(*) from numbers n2 where n2.num <= n.num) as seqnum
      from numbers n
     ) n
     on l.seqnum = n.seqnum;

我发现不使用row_number()的限制相当荒谬,因为它是几乎所有数据库都支持的ISO / ANSI标准功能。

答案 1 :(得分:2)

如果您的SQL版本支持ASCII函数(可以为每个小写字母生成ASCII码),那么您可以加入下移96的ASCII码:

SELECT
    t1.letters,
    t2.nums
FROM table1 t1
INNER JOIN table2 t2
    ON t2.nums = ASCII(t1.letters) - 96;

enter image description here

Demo