Boe*_*ern 11 scala apache-spark apache-spark-sql
我花了很长时间来编写多个SQL查询,这些查询以前用于获取各种R
脚本的数据.这就是它的工作原理
sqlContent = readSQLFile("file1.sql")
sqlContent = setSQLVariables(sqlContent, variables)
results = executeSQL(sqlContent)
Run Code Online (Sandbox Code Playgroud)
线索是,对于某些查询,需要先前查询的结果 - 为什么VIEW
在数据库中创建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)
Run Code Online (Sandbox Code Playgroud)
但这是我非常愚蠢的意见.此外,更复杂的查询,例如,当前无法使用子查询因子的查询不起作用.有没有像重新实现的SQL代码到一个更强大的方式Spark.SQL
使用代码filter($"")
,.select($"")
等等.
总体目标是获得多个org.apache.spark.sql.DataFrame
s,每个s代表一个以前的SQL查询(总是几个JOIN
s,WITH
s等)的结果.所以n
查询导致n
DataFrame
s.
有没有比提供的更好的选择?
设置:Win7工作站上的Hadoop v.2.7.3
,Spark 2.0.0
,Intelli J IDEA 2016.2
,Scala 2.11.8
,Testcluster
目前还不清楚您的要求是什么,但我认为您是说您有类似的疑问:
SELECT * FROM people LEFT OUTER JOIN places ON ...
SELECT * FROM (SELECT * FROM people LEFT OUTER JOIN places ON ...) WHERE age>20
Run Code Online (Sandbox Code Playgroud)
你会想要有效地声明和执行它
SELECT * FROM people LEFT OUTER JOIN places ON ...
SELECT * FROM <cachedresult> WHERE age>20
Run Code Online (Sandbox Code Playgroud)
为了实现这一点,我将增强输入文件,以便每个 sql 语句都有一个关联的表名,结果将存储在其中。
例如
PEOPLEPLACES\tSELECT * FROM people LEFT OUTER JOIN places ON ...
ADULTS=SELECT * FROM PEOPLEPLACES WHERE age>18
Run Code Online (Sandbox Code Playgroud)
然后像这样循环执行
parseSqlFile().foreach({case (name, query) => {
val data: DataFrame = execute(query)
data.createOrReplaceTempView(name)
}
Run Code Online (Sandbox Code Playgroud)
确保按顺序声明查询,以便创建所有必需的表。其他的则进行更多的解析并按依赖关系排序。
在 RDMS 中,我将这些表称为物化视图。即对其他数据(如视图)的转换,但结果会被缓存以供以后重用。
归档时间: |
|
查看次数: |
479 次 |
最近记录: |