2020-09-28

  1. 概述

为与主流数据库兼容,GBase 8s在很多国产化替代项目中做了很多努力,其中,Group By语句对标量函数及表达式的支持问题较为典型,这篇文章会详细阐述一下。

  1. 问题现状
    1. 现状描述

在某国产化替代项目现场出现如下场景:Group By子句需要支持to_char函数分组(包含不在投影列中的字段)。在这种场景下,GBase 8s会报错“SQL错误【ErrorCode:-201】【SQLState:42000】:A syntax error has occurred.”。如下所示:

源SQL:

select

       count(distinct(t.col4)) as psr_num,

       1 as defaulVal,

       t.col2

from test t

where t.col1 > 10

group by t.col2,to_char(t.col5,'YYYY-MM-DD') ;

 

    1. 问题分析

在某主流数据库中对Group By语句对标量函数及表达式支持情况进行测试分析,过程如下。

a.测试表table1结构:

col1

col2

col3

col4

col5

col6

1

2

3

1

2019-10-10 12:12:12

2019-10-11 12:12:12

b.测试过程:

  1. 标量函数
  • 测试SQL:

标量函数:

SQL1: select col2, to_char(col5,'YYYY-MM-DD HH:MM:SS'),count(distinct(col4)) from table1 group by col2, to_char(col5,'YYYY-MM-DD HH:MM:SS');

SQL2: select abs(col2), count(distinct(col4)) from table1 group by abs(col2), col1;

SQL3: select to_char(col5,'YYYY') from table1 group by to_char(col5,'YYYY-MM');

SQL4: select to_char(col2) from table1 group by abs(col2);

SQL5: select col3+abs(col2), count(distinct(col4)) from table1 group by abs(col2), col3;

嵌套函数:

SQL6: select sum(avg(abs(col2))) from table1 group by nvl(col2,col3);

SQL7: select avg(sum(avg(abs(col2)))) from table1 group by nvl(col2,col3);

SQL8: select to_char(abs(abs(col2))) from table1 group by to_char(abs(abs(col2)));

 

  • 测试结果:

SQL1-2、SQL5语句执行成功,SQL3-4语句执行失败,说明标量函数在select投影列中单独存在时需与group by语句中出现的标量函数保持一致,包括函数名称及参数。

SQL6、SQL8语句执行成功,SQL7语句执行失败,说明select投影列中聚合函数最多嵌套两层,而标量函数可无限嵌套,但投影列与group by语句中嵌套的标量函数必须保持一致。

 

  1. 表达式
  • 测试SQL:

算术表达式

SQL1: select col1+col2, count(distinct(col4)) from table1 group by col2+col1, col3;

SQL2: select 1+col2, count(distinct(col4)) from table1 group by col2+1, col3;

SQL3: select col2+1+col3, count(distinct(col4)) from table1 group by col2+1, col3;

SQL4: select col2+col3+1, count(distinct(col4)) from table1 group by col2+1, col3;

比较表达式:

SQL5: select count(col2) from table1 group by col2>1;

逻辑表达式:

SQL6: select count(col2) from table1 group by col2>1 and col2<10;

按位表达式:

SQL7: select count(col2) from table1 group by col2 | col3;

 

  • 测试结果:

SQL1-3:主流数据库均支持。

SQL4-7:均不支持。

说明group by语句后的表达式仅支持算术表达式且遵循交换律,对比较表达式、逻辑表达式和按位表达式并不提供支持。

 

  1. 标量函数+表达式
  • 测试SQL:

SQL1: select 1+abs(col2), count(distinct(col4)) from table1 group by abs(col2)+1, col3;

SQL2: select 1+abs(col2)+col3, count(distinct(col4)) from table1 group by abs(col2)+1, col3;

SQL3: select abs(col2+1) from table1 group by abs(1+col2);

SQL4: select abs(col2)+col3 from table1 group by col3+abs(col2);

SQL5: select sum(abs(col2+1)) from table1 group by 1+col2;

 

SQL6: select abs(col2+col3+1) from table1 group by abs(1+col2+col3);

SQL7: select abs(col2)+col3+1 from table1 group by abs(col2)+1, col3;

SQL8: select abs(col2-1) from table1 group by abs(1-col2);

 

  • 测试结果:

SQL1-5:支持。

SQL6-8:均不支持。

    1. 问题总结

经分析测试,主流数据库对Group By子句存在标量函数和表达式的场景支持较好。

GBase 8s数据库会加强兼容性方面的功能支持,以支持上述场景,降低从主流数据库迁移到GBase 8s数据库的适配难度,提供更强大的兼容能力。

  1. 解决方案

为解决国产化替代过程中出现的较多兼容性要求,涵盖绝大多数Group By语句兼容性场景,GBase 8s 的Group By语句在现有基础上逐步加强对标量表达式的支持,可按照以下方式解决:

  1. 若投影列中存在Group By子句中的标量表达式,则必须与Group By子句中的标量表达式保持一致。
  2. 标量表达式包括:
      • 标量函数,标量函数的参数包含from子句中表的列;
      • 算术表达式,算术表达式中参与运算的元素必须包含from子句中表的列;
      • 标量嵌套函数,嵌套层级与现有GBase 8s规则保持一致;
      • 其他表达式情况与现有系统保持一致。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值