我想连接两个表,其中第一个表的条目比第二个多,这样每个表中的行就可以按顺序连接。也许一个小例子会有所帮助:
表T:
| tid | sid | ron | val | seqno |
| --- | --- | --- | --- | --- |
| 1 | a | x1 | 15 | 1 |
| 2 | b | x2 | 10 | 3 |
| 2 | b | x3 | 20 | 4 |
| 3 | a | x5 | 10 | 5 |
| 4 | c | x9 | 15 | 7 |
| 4 | c | x9 | 15 | 8 |
| 4 | c | x9 | 20 | 10 |
| 4 | c | x9 | 15 | 11 |
| 6 | b | x11 | 22 | 12 |
| 7 | b | x12 | 10 | 14 |
| 7 | b | x13 | 10 | 16 |
| 7 | b | x13 | 10 | 17 |
| 7 | b | x14 | 10 | 19 |
第二个表(表C(如下(实际上是更多的列(:
| tid | sid | ron | val | fid |
| --- | --- | --- | --- | --- |
| 2 | b | x3 | 20 | 54 |
| 4 | c | x9 | 15 | 12 |
| 4 | c | x9 | 15 | 14 |
| 4 | c | x9 | 20 | 15 |
| 4 | c | x9 | 15 | 20 |
| 7 | b | x13 | 10 | 112 |
| 7 | b | x13 | 10 | 113 |
每个表中都有seqNo
和fid
,用于在(tid, sid, ron)
形成的组中提供排序,这就是我想要维护的排序。
我怎样才能从这两张桌子转到下一张桌子?
| tid | sid | ron | val | fid | seqno |
| --- | --- | --- | --- | --- | --- |
| 2 | b | x3 | 20 | 54 | 4 |
| 4 | c | x9 | 15 | 12 | 7 |
| 4 | c | x9 | 15 | 14 | 8 |
| 4 | c | x9 | 20 | 15 | 10 |
| 4 | c | x9 | 15 | 20 | 11 |
| 7 | b | x13 | 10 | 112 | 16 |
| 7 | b | x13 | 10 | 113 | 17 |
我不能为组中的每个元素分配一个秩,并将其用于LEFT JOIN
内部的匹配,因为有些情况下匹配不是从组的末尾开始的(例如tid=7
(。此外,由于同一组中的val
可能有重复的值,我也不能盲目匹配,因为这可能会增加行数。
这是我昨晚设法弄到很晚的东西,似乎工作正常:
WITH
table_t AS (
SELECT *
FROM (VALUES
(1,'a','x1',15,1),
(2,'b','x2',10,3),
(2,'b','x3',20,4),
(3,'a','x5',10,5),
(4,'c','x9',15,7),
(4,'c','x9',15,8),
(4,'c','x9',20,10),
(4,'c','x9',15,11),
(6,'b','x11',22,12),
(7,'b','x12',10,14),
(7,'b','x13',10,16),
(7,'b','x13',10,17),
(7,'b','x14',10,19)
) AS c(tid, sid, ron, val, seq)
),
table_t_ranked AS (
SELECT *
, DENSE_RANK() OVER (PARTITION BY tid, sid, ron ORDER BY seq ASC) AS ranking
FROM table_t
),
table_c AS (
SELECT *
FROM (VALUES
(2,'b','x3',20,54),
(4,'c','x9',15,12),
(4,'c','x9',15,14),
(4,'c','x9',20,15),
(4,'c','x9',15,20),
(7,'b','x13',10,112),
(7,'b','x13',10,113)
) AS c(tid, sid, ron, val, fid)
),
table_c_ranked AS (
SELECT *
, DENSE_RANK() OVER (PARTITION BY tid, sid, ron ORDER BY fid ASC) AS ranking
FROM table_c
),
foo AS (
SELECT c.*
, t.seq
, t.ranking as ranking_t
FROM table_c_ranked c
LEFT JOIN table_t_ranked t
ON c.tid = t.tid
AND c.sid = t.sid
AND c.ron = t.ron
AND c.val = t.val
)
SELECT tid, sid, ron, val, fid, seq
FROM foo
WHERE ranking = ranking_t
ORDER BY tid, seq