有没有更好的方法来编写这个 BigQuery Sql?
Posted
技术标签:
【中文标题】有没有更好的方法来编写这个 BigQuery Sql?【英文标题】:Is there a better way to write this BigQuery Sql? 【发布时间】:2020-09-15 10:45:37 【问题描述】:我有以下 SQL
SELECT CONCAT('method', ' ', r_type, ' ',
r_schema, '.', r_name,
(SELECT
CASE (
SELECT count(*)
FROM myDataset.params
WHERE s_name= 'fileName'
)
WHEN 0 THEN '()'
ELSE
(
SELECT CONCAT('(', STRING_AGG(CONCAT(p_mode, ' ', p_name, ' ', p_type), ', '), ')')
FROM myDataset.params
WHERE s_name = 'fileName'
)
END)
, '\n', r_definition, '\n')
FROM myDataset.routines
WHERE r_name = 'fileName';
它运行以下结果。
method r_type r_schema.r_name(p_mode p_name p_type, ... so on)
r_body
内部查询首先通过检查其计数来检查fileName
是否存在于myDataset.params
中。如果它为零,则返回()
进行连接,否则如果它非零,则对myDataset.params
的所有行执行字符串操作。执行内部查询后,只需执行字符串操作和CONCAT
,它的投影为myDataset.routine
。
我想问有没有更好的方法(更少的代码)在 BigQuery 中编写这个查询。我的意思是查询正在做它的工作,但仍然。
PS:字符串fileName
是一个变量。
【问题讨论】:
【参考方案1】:SELECT CASE
可以替换为 COALESCE
调用,因为当有匹配的行时,CONCAT(p_mode, ' ', p_name, ' ', p_type)
的输出永远不会是 NULL
。
SELECT CONCAT('method', ' ', r_type, ' ', r_schema, '.', r_name,
(SELECT COALESCE(CONCAT('(',
STRING_AGG(
CONCAT(p_mode, ' ', p_name, ' ', p_type),
', '),
')'),
'()')
FROM myDataset.params
WHERE s_name = 'fileName'),
'\n', r_definition, '\n')
FROM myDataset.routines
WHERE r_name = 'fileName';
另外,您可以尝试使用LEFT JOIN
而不是子查询...这取决于最终的WHERE
子句是否是动态的(它总是“文件名”吗?):
SELECT CONCAT('method', ' ', r_type, ' ', r_schema, '.', r_name,
mode_name_type, '\n', r_definition, '\n')
FROM myDataset.routines r
LEFT JOIN (
SELECT COALESCE(CONCAT('(',
STRING_AGG(
CONCAT(p_mode, ' ', p_name, ' ', p_type),
', '),
')'),
'()') mode_name_type,
s_name
FROM myDataset.params
GROUP BY s_name
) p on p.s_name = r.r_name
WHERE r.r_name = 'fileName';
【讨论】:
以上是关于有没有更好的方法来编写这个 BigQuery Sql?的主要内容,如果未能解决你的问题,请参考以下文章
子选择或连接?有没有更好的方法来编写这个 mysql 查询?