开发者社区> 问答> 正文

关于union all 的解析时获取不到QueryBlock的问题

SQL: SELECT LATN_ID , CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END AS BUREAU_KEY, SUM(COALESCE(ADD_USER_CNT, 0)) AS ADD_SUM , 0 AS USER_ACCT, 0 AS USER_ACCT_LY FROM MK.M_BROAD_BAND_USER_FACT WHERE THE_DATE BETWEEN SUBSTR('{THISMONTH}', 1, 4) || '-01-01' AND '{THISMONTH}' GROUP BY LATN_ID, CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END UNION ALL SELECT LATN_ID , CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END AS BUREAU_KEY, 0 AS ADD_SUM , SUM(COALESCE(BILL_USER_CNT, 0)) AS USER_ACCT , 0 AS USER_ACCT_LY FROM MK.M_BROAD_BAND_USER_FACT WHERE THE_DATE = '{THISMONTH}' GROUP BY LATN_ID, CASE WHEN BUREAU_KEY = 116 THEN 46 ELSE BUREAU_KEY END; 解析时发现获取到的QueryBlock是null,导致了获取不到selectlist。请问是什么原因导致的?

原提问者GitHub用户johnchenjy

展开
收起
山海行 2023-07-05 20:40:29 101 0
4 条回答
写回答
取消 提交回答
  • 对于包含UNION ALL的SQL语句,Druid解析器在解析时会将其拆分为多个子查询,并分别进行解析。每个子查询都会构建一个QueryBlock对象来表示其语义。

    根据您提供的代码片段,如果在获取QueryBlock对象时返回null,可能是由于以下原因导致的:

    1. 子查询的语法错误:请确保每个子查询都是合法的SQL语句,没有语法错误。可以尝试将每个子查询单独执行并验证其语法是否正确。

    2. 查询中包含非法的表名或列名:检查查询中使用的表名和列名是否存在,是否正确引用了数据库中的实际表和列。如果存在拼写错误或者表、列不存在的情况,可能导致解析失败。

    3. 查询中使用了不支持的特性或功能:Druid解析器可能不支持某些高级的SQL语法特性或功能。请确保查询中没有使用这些不被支持的特性,或尝试简化查询以确定具体的问题所在。

    4. Druid解析器版本不兼容:不同版本的Druid解析器可能存在一些差异和兼容性问题。请确保您使用的Druid解析器版本与您的代码和环境兼容。

    另外,您提到了使用SQLUnionQuery的方式可以获取到QueryBlock对象。这种方法可以尝试,但需要注意确保代码的稳定性和兼容性。

    如果以上方法仍然无法解决问题,建议查阅Druid的官方文档、GitHub仓库或寻求相关技术支持以获取更多帮助。

    2023-07-30 14:05:09
    赞同 展开评论 打赏
  • 北京阿里云ACE会长

    对于包含UNION ALL的SQL语句,Druid解析器在解析时会将其拆分为多个子查询,然后分别解析。每个子查询都会构建一个QueryBlock对象来表示其语义。但是,在UNION ALL的情况下,Druid解析器无法确定每个子查询的列名和列类型,因此会默认使用第一个子查询的列名和列类型。这可能会导致在某些情况下获取不到正确的列名和列类型。

    对于这个问题,您可以尝试以下方法解决:

    在解析UNION ALL类型的SQL语句时,遍历所有子查询并获取所有列名和列类型,然后将它们合并到一个虚拟的QueryBlock对象中。这个虚拟的QueryBlock对象可以作为整个UNION ALL操作的查询块,用于获取正确的列名和列类型。

    使用SELECT *语句替代UNION ALL语句,然后使用ResultSetMetaData获取所有列名和列类型。这个方法可能会影响查询性能,因为需要执行多次查询来获取列信息。

    如果您使用的是MySQL数据库,可以通过执行DESCRIBE语句获取表的列名和列类型

    2023-07-30 13:46:06
    赞同 展开评论 打赏
  • 可以看出该查询是一个联合查询,包含两个子查询,然后将子查询的结果进行union操作。可能是由于子查询返回的结果集不符合要求,导致无法将其转换为QueryBlock对象,从而无法获取到selectlist。具体原因需要看一下代码实现,可能是由于某些条件限制,导致无法将某些子查询结果集转换为QueryBlock对象。

    2023-07-11 10:11:51
    赞同 展开评论 打赏
  • 发现使用SQLUnionQuery unionQuery = (SQLUnionQuery) select.getQuery();就能获取到了

    原回答者GitHub用户johnchenjy

    2023-07-06 11:53:29
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
低代码开发师(初级)实战教程 立即下载
冬季实战营第三期:MySQL数据库进阶实战 立即下载
阿里巴巴DevOps 最佳实践手册 立即下载