我想在一个与第一个上一个记录匹配的密钥上加入2个表。
我有一个查询来执行此操作。但是,我还想在每个表的结果中包含一列。这迫使我在Group By属性中包含这两个列,这将返回重复的结果。
我使用的查询与此类似(礼貌:stackoverflow):
SELECT t1.frame as frame1,
t1.string as string1,
max(t2.frame) as frame2,
t2.string as string2
FROM t1
JOIN t2
ON t2.frame < t1.frame and
t1.key=t2.key
GROUP BY t1.frame, t2.frame, t1.string, t2.string
ORDER BY t2.frame
我看到的(问题)输出是:
frame1, string1, frame2, string2
51 text1 6 text2
107253 text3 6 text2
如何在我的结果中包含string2,以便我不想按其分组,但只包含相应frame2的值?
我尝试在sqlfiddle.com上进行设置,以便于尝试。我填充了一些虚拟数据但是这里连同这个问题,我还看到另一个问题,即它也返回结果,其中frame2 = 2。这不是预期的,因为它应始终匹配frame = 6。我想这可能是字符串分组的副作用?
这里我希望输出只能是1条记录:
frame1,string1,frame2,string2
51 text1 6 text2
我在Spark SQL上这样做,但这应该是一个通用的SQL问题。 感谢。
编辑: 我的数据由传入的数据包组成,我希望将数据包与之前的最新数据包匹配,该数据包具有匹配的ID。例如,
Table t2:
frame#1:Key=a,Text=abc
frame#2:Key=a,Text=def
frame#3:Key=b,Text=efg
frame#5:Key=c,Text=xyz
Table t1:
frame#4:Key=a,Text=pqr
frame#6:Key=c,Text=mno
所以在这里,对于来自t1的帧#4,我希望将它与来自t2的帧匹配,并且具有相同的键。因此它应该与帧#2匹配(不是帧#3 coz键是不同的而不是帧#1因为帧#2是更新的)。同样,帧#6应与帧#5匹配。
希望现在很清楚。
答案 0 :(得分:1)
SELECT A.*, t1.string AS string1, t2.string AS string2
FROM
(SELECT t1.frame AS frame1, MAX(t2.frame) AS frame2
FROM t1
INNER JOIN t2 ON t1.key=t2.key AND t2.frame< t1.frame
GROUP BY t1.frame
) A
INNER JOIN t1 ON A.frame1=t1.frame
INNER JOIN t2 ON A.frame2=t2.frame;
输出:
frame1 frame2 string1 string2
1 51 6 text13 text17
2 107253 106999 text25 text39
答案 1 :(得分:0)
这个查询将表格剥离为“只是最新的行”,其中“latest”被定义为“具有键列的最高int值”。
这就是row_number()over()函数的作用;为行分配一个递增的数字,每当密钥更改时重新启动它,具有相同密钥的行按帧递减排序,因此最新的总是rownumber 1
SELECT
a.frame as frame1,
a.string as string1,
b.frame as frame2
FROM
(SELECT
frame,
key,
string,
row_number() over(partition by key order by frame desc) as rown
from t1
) a
INNER JOIN
(SELECT
frame,
key,
string,
row_number() over(partition by key order by frame desc) as rown
from t2
) b
ON a.rown = 1 and a.key = b.key and b.rown=1
如果您需要更改“最新”的定义,请将顺序更改为升序(它将给出最低的帧数)
如果按照我的评论你的“第一个上一个”的定义不同,即你想要最新的行,(其中一个更高的键号是“更晚”)然后在ON子句中使它rown = 2,并使按排序是按键降序
(如果您只是自己运行子查询,它可能对您有帮助,然后查看数据并说“我想要的行总是有一个 rown 的X”)
更新
我怀疑你最近的更新中你希望ON子句在rown = 2的地方可能是你的一个表,如果不是另一个。因为我不清楚你的哪一个表是“落后”,所以你必须在sqlfiddle中编辑上面的答案。这是一个产生你请求的输出的版本
SELECT
a.frame as frame1,
a.string as string1,
b.frame as frame2,
b.string
FROM
(SELECT
frame,
key,
string,
row_number() over(partition by key order by frame desc) as rown
from t1
) a
INNER JOIN
(SELECT
frame,
key,
string,
row_number() over(partition by key order by frame desc) as rown
from t2
) b
ON a.rown = 2 and a.key = b.key and b.rown=1
您可能希望在较大的数据集上进行测试
答案 2 :(得分:0)
http://sqlfiddle.com/#!17/47c11/2
select distinct on (t.frame1, t.key1, t.string1)
t.*
from
(select
t1.frame frame1, t1.key key1, t1.string string1, t2.frame frame2, t2.key key2, t2.string string2
from
t1
join
t2
on
t1.key=t2.key
and t1.frame > t2.frame
order by
t2.frame desc) t