我有一个原始文本中的sql查询数据集,还有一个包含所有可能表名的正则表达式:
# queries
+-----+----------------------------------------------+
| id | query |
+-----+----------------------------------------------+
| 1 | select * from table_a, table_b |
| 2 | select * from table_c join table_d... |
+-----+----------------------------------------------+
# regexp
'table_a|table_b|table_c|table_d'
我希望得到以下结果:
# expected result
+-----+----------------------------------------------+
| id | tables |
+-----+----------------------------------------------+
| 1 | [table_a, table_b] |
| 2 | [table_c, table_d] |
+-----+----------------------------------------------+
但是在spark中使用下面的sql,我得到的只是第一个匹配。。。
select
id,
regexp_extract(query, 'table_a|table_b|table_c|table_d') as tables
from queries
# actual result
+-----+----------------------------------------------+
| id | tables |
+-----+----------------------------------------------+
| 1 | table_a |
| 2 | table_c |
+-----+----------------------------------------------+
有没有办法只用sparksql来实现这一点?这就是我正在使用的函数https://people.apache.org/~pwendell/spark-nightly/spark-master-docs/latest/api/sql/#regexp_extract
编辑
我也会接受返回以下内容的解决方案:
# alternative solution
+-----+----------------------------------------------+
| id | tables |
+-----+----------------------------------------------+
| 1 | table_a |
| 1 | table_b |
| 2 | table_c |
| 2 | table_d |
+-----+----------------------------------------------+
解决方案
@chlebek在下面解决了这个问题。为了提高可读性,我使用CTE重新格式化了他的sql:
with
split_queries as (
select
id,
explode(split(query, ' ')) as col
from queries
),
extracted_tables as (
select
id,
regexp_extract(col, 'table_a|table_b|table_c|table_d', 0) as rx
from split_queries
)
select
id,
collect_set(rx) as tables
from extracted_tables
where rx != ''
group by id
请记住 split(query, ' ')
部分查询将仅按空格分割sql。如果你有其他事情,如制表符,换行符,注解等,你应该处理这些之前或分裂时。
4条答案
按热度按时间ttp71kqs1#
当您使用sparksql时,您可以使用sql解析器&它将为您完成这项工作。
您可以将“gettables”注册为udf并在查询中使用
deikduxw2#
您可以使用spark中的另一个sql函数collect\u listhttps://docs.databricks.com/spark/latest/spark-sql/language-manual/functions.html#collect_list. 你可以再找一个样品https://mungingdata.com/apache-spark/arraytype-columns/
基本上,应用到代码中
输出将是
希望这有帮助
ndh0cuux3#
如果你在
spark>=2.4
然后你可以移除exploding
以及collecting the same
在数组上使用高阶函数而不使用任何子查询的操作-加载测试数据
从查询中提取表
von4xj4u4#
如果只需要检查几个值,则可以使用
contains
函数而不是regexp:但使用regexp时,它将如下所示(spark sql api):
可以转换为以下sql查询:
因此,输出将是: