2017-06-14 63 views
0

假设我有两个表,并且它们都有一个包含各种事件的timestamp的列。两个表中的时间戳值都不同,因为它们对于不同的事件。 我想加入两个表,使table1中的每个记录都与table2上的第一个较低时间戳结合。SQL连接,其中第二个表中的值为第一个较低值w.r.t第一个表

For e.g. 
Table1  Table2 
142.13  141.16 
157.34  145.45 
168.45  155.85 
170.23  166.76 
      168.44 

Joined Table should be: 
142.13,141.16 
157.34,155.85 
168.45,166.76 
170.23,168.44 

我正在使用Apache Spark SQL。

我是SQL中的noob,这看起来不像noob的工作:)。谢谢。

+1

您使用的是什么RDBMS? –

+0

如果您在其中一个表格中有更多记录,该怎么办?他们应该被排除在外吗? –

+0

我正在使用Spark SQL。谢谢。 –

回答

1

同上显示了直接解决这个问题的方法。如果Apache星火真的有问题,这个非常基本的查询,然后再加入第一(这可能会导致一个很大的中间结果),然后汇总:

select t1.v, max(t2.v) 
from table1 t1 
join table2 t2 on t2.v <= t1.v 
group by t1.v 
order by t1.v; 
+0

Yayy !!这似乎工作。尝试了一些虚拟数据。明天将尝试使用真实数据。非常感谢。你们真棒。从未收到过这种快速回复。祝你有美好的一天。 :) –

+0

请看我的问题[这里](https://stackoverflow.com/questions/44944087/sql-join-with-selecting-previous-matching-value-with-group-by/44945322?noredirect=1#comment76867110_44945322 )。此查询不适用于此数据集。你可以请建议适当的修改?谢谢。 http://sqlfiddle.com/#!17/7c270/3/0 –

3

试试这个:

with t1 as (
      select 142.13 v from dual union all 
      select 157.34 v from dual union all 
      select 168.45 v from dual union all 
      select 170.23 v from dual 
     ), 
     t2 as (
     select 141.16 v from dual union all 
     select 145.45 v from dual union all 
     select 155.85 v from dual union all 
     select 166.76 v from dual union all 
     select 168.44 v from dual 
     ) 
    select v, (select max(v) from t2 where t2.v <= t1.v) 
    from t1; 


      V (SELECTMAX(V)FROMT2WHERET2.V<=T1.V) 
    ---------- ----------------------------------- 
     142.13        141.16 
     157.34        155.85 
     168.45        168.44 
     170.23        168.44 

    4 rows selected. 

WITH子句仅仅是我伪造的数据... 简化查询就是:

select t1.v, (select max(t2.v) from table2 t2 where t2.v <= t1.v) from table1 t1 

[编辑] 诚然,我不熟悉Spark ..但是这足够简单SQL ..我假设它的工作原理:)

+0

我试图将其转换为Spark SQL,但它失败并且出现一个可怕的错误。最后一个'/'在这里做什么?这是我的Spark SQL查询。 '选择frame_number,(从t2中选择max(frame_number),其中t2.frame_number <= t1.frame_number)从t1开始。可怕的错误是'相关列不允许在不等于谓词中' –

+0

看看错误,看起来像Spark SQL不支持两个值不相等的相关查询。我读过这些吗? –

+0

@Nikhil:好吧..所以忽略最后的“/”..这只是平台上的小语法差异。但除此之外,做一个快速搜索,似乎Spark应该支持基本的ANSI sql ..这意味着查询,因为我有它应该工作。你必须改变你的表名和列名,因为你没有在你的例子中提供它们。如果您提供更多详细信息,我会更新我的答案以更好地匹配您的详细信息。 – Ditto

0

如果您使用的是Apache火花SQL那么你可以连接这两个表作为与添加使用monotonically_increasing_id()

val t1 = spark.sparkContext.parallelize(Seq(142.13, 157.34, 168.45, 170.23)).toDF("c1") 
val t2 = spark.sparkContext.parallelize(Seq(141.16,145.45,155.85,166.76,168.44)).toDF("c2") 

val t11 = t1.withColumn("id", monotonically_increasing_id()) 
val t22 = t2.withColumn("id", monotonically_increasing_id()) 

val res = t11.join(t22, t11("id") + 1 === t22("id")).drop("id") 

输出列dataframes:

+------+------+ 
| c1| c2| 
+------+------+ 
|142.13|145.45| 
|168.45|166.76| 
|157.34|155.85| 
|170.23|168.44| 
+------+------+ 

希望这有助于

+0

c2的第一个输出不正确。这里应该是141.16。谢谢。 –

+0

这不是你问的问题:“我想加入两个表,这样table1中的每个记录都与table2上的第一个较低时间戳结合在一起。” –

+0

是的,所以142.13应该与141.16相连,它只是低于142.13。 –

相关问题