Scala&;Spark:回收SQL语句

Scala&;Spark:回收SQL语句,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我花了相当长的时间编写了多个SQL查询,这些查询以前用于获取各种R脚本的数据。这就是它的工作原理 sqlContent = readSQLFile("file1.sql") sqlContent = setSQLVariables(sqlContent, variables) results = executeSQL(sqlContent) 线索是,对于某些查询,需要先前查询的结果-为什么在数据库中创建视图s本身并不能解决此问题。通过使用Spark 2.0,我已经找到了一种方法 // crea

我花了相当长的时间编写了多个SQL查询,这些查询以前用于获取各种
R
脚本的数据。这就是它的工作原理

sqlContent = readSQLFile("file1.sql")
sqlContent = setSQLVariables(sqlContent, variables)
results = executeSQL(sqlContent)
线索是,对于某些查询,需要先前查询的结果-为什么在数据库中创建
视图
s本身并不能解决此问题。通过使用Spark 2.0,我已经找到了一种方法

// create a dataframe using a jdbc connection to the database
val tableDf = spark.read.jdbc(...)
var tempTableName = "TEMP_TABLE" + java.util.UUID.randomUUID.toString.replace("-", "").toUpperCase
var sqlQuery = Source.fromURL(getClass.getResource("/sql/" + sqlFileName)).mkString
sqlQuery = setSQLVariables(sqlQuery, sqlVariables)
sqlQuery = sqlQuery.replace("OLD_TABLE_NAME",tempTableName)
tableDf.createOrReplaceTempView(tempTableName) 
var data = spark.sql(sqlQuery)
但在我看来,这是非常微妙的。此外,更复杂的查询,例如不匹配子查询分解的查询目前不起作用。有没有更可靠的方法,比如使用
过滤器($)
。选择($)
,等等,将SQL代码重新实现到
Spark.SQL
代码中

总体目标是获得多个
org.apache.spark.sql.DataFrame
s,每个都代表一个以前的sql查询的结果(总是有几个
JOIN
s、
WITH
s等)。因此
n
查询将导致
n
DataFrame
s

有没有比提供的两个更好的选择


设置:Hadoop
v.2.7.3
、Spark
2.0.0
、Intelli J IDEA
2016.2
、Scala
2.11.8
、Win7工作站上的Testcluster

您的要求不是特别明确,但我想您是说您有如下疑问:

SELECT * FROM people LEFT OUTER JOIN places ON ...
SELECT * FROM (SELECT * FROM people LEFT OUTER JOIN places ON ...) WHERE age>20
您希望按照以下方式高效地声明和执行此操作:

SELECT * FROM people LEFT OUTER JOIN places ON ...
SELECT * FROM <cachedresult> WHERE age>20
然后在循环中执行,如

parseSqlFile().foreach({case (name, query) => {
    val data: DataFrame = execute(query)
    data.createOrReplaceTempView(name)
}
确保按顺序声明查询,以便创建所有必需的表。另一种方法是根据依赖项进行更多的解析和排序


在RDMS中,我将这些表称为实体化视图。i、 e.对其他数据(如视图)进行转换,但将结果缓存以供以后重用。

我没有完全理解。您在一个sql文件中有多个查询,并且希望最终将每个查询注册为TempView?还是多个sql文件,每个sql文件有一个查询,每个查询注册一个TempView?我看不出问题出在哪里。后者,谢谢!我添加了一些信息来说明这一点。好的,那么您需要n个sql文件中的n个数据帧。在您添加的代码中已经解决了这个问题。什么是你的解决方案中的“精巧”,为什么你需要“更好”的解决方案-答案应该优化什么?谢谢!我的代码并不能解决这个问题——至少我是如何理解它的
sql()
只能与已注册的临时视图一起使用(
df.createOrReplaceTempView(“人员”)
需要在
val sqlDF=spark.sql(“从人员中选择*)
之前执行)。这使得在需要多个表/视图来生成数据的场景中(例如,使用
FROM
JOIN
s的组合)无法使用它(据我可能有限的理解)。解决我的问题(我通过讨论得出了这一点)的方法是“使用此SQL,对数据库运行它并返回一个数据帧”。另一种方法是,如果可以在使用
spark.SQL()
时指定连接字符串(如
spark.read.jdbc()
parseSqlFile().foreach({case (name, query) => {
    val data: DataFrame = execute(query)
    data.createOrReplaceTempView(name)
}