Spark SQL:如何减少一对多关系
Spark SQL: How to reduce one-to-many relationship
我有以下 dataframe/table:
id|counter
23534074|1
23534074|2
23534074|3
24142005|1
24142005|2
并且我想将其减少为仅具有不同的 ID(例如,采用第一个 ID 行)。因此,生成的数据框应如下所示:
id|counter
23534074|1
24142005|1
这是我目前所做的:
我用以下方法读取数据:
val tf = sqlContext.read.format("com.databricks.spark.csv")
.option("header", "true")
.option("delimiter", "|")
.load("test.csv")
使用
创建一个临时表
tf.registerTempTable("TF")
这就是我尝试在 "id"
上获得独特性的方法
sqlContext.sql("select distinct(id),counter from TF group by id,counter").show
但它没有给我预期的结果:
+--------+-------+
| id|counter|
+--------+-------+
|23534074| 1|
|23534074| 2|
|23534074| 3|
|24142005| 1|
|24142005| 2|
+--------+-------+
关于如何使用 Spark SQL 执行此操作的任何想法?
谢谢!
不太清楚您的要求是什么,所以这里有几个选项:
对 counter
列的简单过滤,这假设计数器是唯一的并且 1 是您想要的值
tf.where($"counter" === 1)
相当于:
SELECT * FROM tf WHERE counter = 1
using groupBy
with first(这里没有顺序保证,你得到的只是第一个遇到的值):
tf.groupBy($"id").agg(first($"counter")).show
相当于:
SELECT id, FIRST(counter) AS counter FROM tf GROUP BY id
window 函数,这在计数器提供一些排序并且您想要最低/最高值时很有用
import org.apache.spark.sql.expressions.Window
import org.apache.spark.sql.functions.rowNumber
val w = Window.partitionBy($"id").orderBy($"counter")
tf.withColumn("rn", rowNumber.over(w)).where($"rn" === 1).drop("rn")
相当于
SELECT id, counter FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY counter) rn FROM tf
) tmp WHERE rn = 1
我有以下 dataframe/table:
id|counter
23534074|1
23534074|2
23534074|3
24142005|1
24142005|2
并且我想将其减少为仅具有不同的 ID(例如,采用第一个 ID 行)。因此,生成的数据框应如下所示:
id|counter
23534074|1
24142005|1
这是我目前所做的:
我用以下方法读取数据:
val tf = sqlContext.read.format("com.databricks.spark.csv")
.option("header", "true")
.option("delimiter", "|")
.load("test.csv")
使用
创建一个临时表tf.registerTempTable("TF")
这就是我尝试在 "id"
上获得独特性的方法sqlContext.sql("select distinct(id),counter from TF group by id,counter").show
但它没有给我预期的结果:
+--------+-------+
| id|counter|
+--------+-------+
|23534074| 1|
|23534074| 2|
|23534074| 3|
|24142005| 1|
|24142005| 2|
+--------+-------+
关于如何使用 Spark SQL 执行此操作的任何想法? 谢谢!
不太清楚您的要求是什么,所以这里有几个选项:
对
counter
列的简单过滤,这假设计数器是唯一的并且 1 是您想要的值tf.where($"counter" === 1)
相当于:
SELECT * FROM tf WHERE counter = 1
using
groupBy
with first(这里没有顺序保证,你得到的只是第一个遇到的值):tf.groupBy($"id").agg(first($"counter")).show
相当于:
SELECT id, FIRST(counter) AS counter FROM tf GROUP BY id
window 函数,这在计数器提供一些排序并且您想要最低/最高值时很有用
import org.apache.spark.sql.expressions.Window import org.apache.spark.sql.functions.rowNumber val w = Window.partitionBy($"id").orderBy($"counter") tf.withColumn("rn", rowNumber.over(w)).where($"rn" === 1).drop("rn")
相当于
SELECT id, counter FROM ( SELECT *, ROW_NUMBER() OVER (PARTITION BY id ORDER BY counter) rn FROM tf ) tmp WHERE rn = 1