Order by and Join in SQL 或 spark 或 mapreduce
Order by and Join in SQL or spark or mapreduce
我有两个表格,其内容如下。
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连接。如果存在活动记录,则它应该 return 活动记录。但如果仅存在非活动记录,则应加入最旧的非活动记录。
我尝试了不同的查询,但它们不再接近我想要的答案。
加入的四列都是非主字段但不是空值。两个表之间可以是一对多或多对多的关系。
我正在研究 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)
谁能帮帮我吗?
我只能代表Spark。就右外连接和四个连接列而言,查询看起来是正确的。
在 Spark 中(以及 ANSI 中的 AFAIK sql),顺序不是您显示的方式而是:
order by status, date
您不能针对 Table 1 进行直接连接。相反,您必须针对 Table 1 的多个查询进行连接,这些查询本身连接在一起。根据我的计算,你将不得不做:
- 为每个 ID3、ID4 等查找 table 1 中
ACTIVE
记录的最小值 date
的查询
- 为 table 1
中的 INACTIVE
条记录查找最小值 date
的查询
- 以上两个查询之间的全外连接
coalesce
到 select ACTIVE
与 INACTIVE
字段。
像这样:
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"
)
根据上面的 table 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"
)
这应该会为您提供您最初寻找的结果。
我有两个表格,其内容如下。
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连接。如果存在活动记录,则它应该 return 活动记录。但如果仅存在非活动记录,则应加入最旧的非活动记录。
我尝试了不同的查询,但它们不再接近我想要的答案。 加入的四列都是非主字段但不是空值。两个表之间可以是一对多或多对多的关系。
我正在研究 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)
谁能帮帮我吗?
我只能代表Spark。就右外连接和四个连接列而言,查询看起来是正确的。
在 Spark 中(以及 ANSI 中的 AFAIK sql),顺序不是您显示的方式而是:
order by status, date
您不能针对 Table 1 进行直接连接。相反,您必须针对 Table 1 的多个查询进行连接,这些查询本身连接在一起。根据我的计算,你将不得不做:
- 为每个 ID3、ID4 等查找 table 1 中
ACTIVE
记录的最小值date
的查询 - 为 table 1 中的
- 以上两个查询之间的全外连接
coalesce
到 selectACTIVE
与INACTIVE
字段。
INACTIVE
条记录查找最小值 date
的查询
像这样:
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"
)
根据上面的 table 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"
)
这应该会为您提供您最初寻找的结果。