我是Apache Spark(和Scala)的新手,我想在读取csv文件并将其加载到DF之后立即应用一个简单的sql请求,而无需创建其他数据框或临时视图或表。< / p>
这是最初的请求:
SELECT DISTINCT city from cities
WHERE id IN ("10", "20")
AND year IN ("2017", "2018")
这是我在Scala上尝试过的:
val cities = spark.read.options(Map("header" -> "true", "delimiter" -> ";")).csv("test.csv").select("city").distinct.where(""" id IN ("10", "20") AND year IN ("2017", "2018")"""))
cities.show(20)
但是它不起作用。具体来说,似乎是由于无法识别数据框中的其他两列而导致出现此问题(因为我之前只选择了一列)。因此,我必须首先选择这三列,然后保存一个临时表(视图),然后在新数据框中选择所需的列。我发现这种方法太长太重。
您能帮我解决这个问题吗??? 谢谢!
答案 0 :(得分:1)
您的解决方案几乎是正确的,您只需要将where
语句移到select(..).distinct
之前:
val cities = spark.read
.options(Map("header" -> "true", "delimiter" -> ";"))
.csv("test.csv")
.where($"id".isin("10", "20") and $"year".isin("2017", "2018"))
.select("city").distinct
答案 1 :(得分:0)
Spark scala API比声明性命令更重要(与SQL不同),这就是为什么在select("city")
之后丢失数据帧中所有其他字段的原因。以及其他人指出的原因,在进行选择之前,应先过滤/位置。这有点令人困惑,因为Scala DSL的语法类似于SQL
答案 2 :(得分:0)
如sramalingam24和Raphael Roth所述,在从DataFrame中选择所需字段之前,必须先应用where
。过滤器和两者都给出相同的结果,如下所示。 dropDuplicates()将删除城市列中的重复项。
val cities = spark.read.options(Map("header" -> "true", "delimiter" -> ";"))
.csv("test.csv")
.filter($"id".isin("10", "20") and $"year".isin("2017", "2018"))
.select("city")
.dropDuplicates()