0

我有两个表格,其内容如下。

Table 1:
ID1     ID2     ID3    ID4                NAME    DESCR   STATUS        date   
1    -12134    17773    8001300701101    name1    descr1    INACTIVE    20121203
2    -12136    17773    8001300701101    name1    descr1    INACTIVE     20121202
3    -12138    17785    9100000161822    name3    descr3    INACTIVE    20121201
4    -12140    17785    9100000161822    name3   descr3    ACTIVE        20121130
5    -12142    17787    8000500039106    name4    descr4    ACTIVE        20121129

Table2:
ID1    ID2         ID3        ID4       NAME    DESCR  
0    17781    17773    8001300701101    name1    descr1
0    17783    17783    8001300060109    name2    descr2
0    17785    17785    9100000161822    name3    descr3
0    17787    17787    8000500039106    name4    descr4
0    17789    17789    0000080052364    name5    descr5

我试图得到低于结果。

ID3        ID4            NAME     DESCR      STATUS        date        
17773    8001300701101    name1    descr1      INACTIVE    20121202
17783    8001300060109    name2    descr2      NULL        NULL
17785    9100000161822    name3    descr3      ACTIVE      20121201
17787    8000500039106    name4    descr4      ACTIVE      20121129
17789    0000080052364    name5    descr5      NULL        NULL

根据上面的 i/p 和 o/p,这两个表应该基于列 id3、id4、name 和 desc 连接。如果存在活动记录,则应返回活动记录。但如果仅存在非活动记录,则应加入最旧的非活动记录。

我尝试了不同的查询,这些查询不再接近我想要的答案。连接的四列都是非主字段,但不是空值。两个表之间可以存在一对多或多对多的关系。

我正在研究 Apache phoenix,如果解决方案在 Hadoop Mapreduce 或 Apache Spark 中也可以。

我写的一个示例查询如下。

Select table2.*, table1.status, table1.date 
From table1 Right outer join table2 on table1.id3 = table2.id3 
            and  table1.id4 = table2.id4 
            and table1.name = table2.name 
            and table1.descr = table2.descr 
Order by (status) and order by (date)

任何人都可以帮助我吗?

4

2 回答 2

1

您不能对表 1 进行直接连接。相反,您必须对表 1 的多个查询进行连接,这些查询本身是连接在一起的。根据我的计算,你将不得不这样做:

  1. 查找表 1 中每个 ID3、ID4 等记录的最小值的查询dateACTIVE
  2. 查找表 1 中记录date的最小值的查询INACTIVE
  3. 上述两个查询之间的完全外连接
  4. coalesce选择ACTIVEINACTIVE字段。

像这样的东西:

val cookedTable1 = table1.filter(
  $"STATUS" === "ACTIVE"
).groupBy(
  $"ID3", $"ID4", $"NAME", $"DESCR", $"STATUS"
).agg(
  $"ID3", $"ID4", $"NAME", $"DESCR", $"STATUS", min($"date") as "date"
).join(
  table1.filter(
    $"STATUS" === "INACTIVE"
  ).groupBy(
    $"ID3", $"ID4", $"NAME", $"DESCR", $"STATUS"
  ).agg(
    $"ID3", $"ID4", $"NAME", $"DESCR", $"STATUS", min($"date") as "date"
  ).select(
    $"ID3" as "ID3r", $"ID4" as "ID4r", $"NAME" as "NAMEr", $"DESCR" as "DESCRr",
    $"STATUS" as "STATUSr", $"date" as "dater"
  ),
  $"ID3" === $"ID3r" and $"ID4" === $"ID4r" and $"NAME" === $"NAMEr" and $"DESCR" === $"DESCRr", 
  "full_outer"
)
.select(
  coalesce($"ID3", $"ID3r") as "ID3", 
  coalesce($"ID4",$"ID4r") as "ID4", 
  coalesce($"NAME", $"NAMEr") as "NAME",
  coalesce($"DESCR", $"DESCRr") as "DESCR",
  coalesce($"STATUS", $"STATUSr") as "STATUS",
  coalesce($"date", $"dater") as "date"
)

鉴于您在上表 1 中的内容,结果将如下所示:

cookedTable1.show

ID3   ID4           NAME  DESCR  STATUS   date
17785 9100000161822 name3 descr3 ACTIVE   20121130
17787 8000500039106 name4 descr4 ACTIVE   20121129
17773 8001300701101 name1 descr1 INACTIVE 20121202

现在,使用cookedTable1代替table1,执行与之前相同的查询:

cookedTable1.registerTempTable("cookedTable1")
val results = sqlContext("Select table2.*, cookedTable1.status, cookedTable1.date
  From cookedTable1 Right outer join table2 on cookedTable1.id3 = table2.id3
    and cookedTable1.id4 = table2.id4
    and cookedTable1.name = table2.name
    andcookedTable1.descr = table2.descr"
)

这应该会为您提供您最初寻找的结果。

于 2015-05-31T05:18:40.097 回答
0

我只能代表 Spark。就右外连接和四个连接列而言,查询显示正确。

在 Spark(和 ANSI sql 中的 AFAIK)中,顺序不是您显示的方式,而是:

order by status, date
于 2015-05-30T19:12:44.683 回答