有没有更好的方法来编写这个 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?的主要内容,如果未能解决你的问题,请参考以下文章

有没有更好的方法来编写这个 SparkSQL 语句?

子选择或连接?有没有更好的方法来编写这个 mysql 查询?

有没有更好、更干净的方法来编写这个本地存储数据

有没有更好的方法来编写这个处理比较两个不同列中的日期的 Oracle SQL?

有没有更好的方法在 python 中编写这个脚本

有没有更好的方法通过 PySpark 集群(dataporc)将 spark df 加载到 BigQuery 中?