ITPub博客

首页 > 数据库 > 国内数据库 > 南大通用GBase 8s_GROUP BY支持标量函数和表达式问题详解

南大通用GBase 8s_GROUP BY支持标量函数和表达式问题详解

原创 国内数据库 作者:CallMeJasonGao 时间:2020-09-28 16:54:51 1 删除 编辑

1        概述

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

2        问题现状

2.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') ;

 

2.2     问题分析

在某主流数据库中对 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. 测试过程:

l   标量函数

Ø   测试 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 语句中嵌套的标量函数必须保持一致。

 

l   表达式

Ø   测试 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 语句后的表达式仅支持算术表达式且遵循交换律,对比较表达式、逻辑表达式和按位表达式并不提供支持。

 

l   标量函数 + 表达式

Ø   测试 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: 均不支持。

2.3     问题总结

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

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

3        解决方案

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

1)         若投影列中存在 Group By 子句中的标量表达式,则必须与 Group By 子句中的标量表达式保持一致。

2)         标量表达式包括:

Ø   标量函数,标量函数的参数包含 from 子句中表的列;

Ø   算术表达式,算术表达式中参与运算的元素必须包含 from 子句中表的列;

Ø   标量嵌套函数,嵌套层级与现有 GBase 8s 规则保持一致;

Ø   其他表达式情况与现有系统保持一致。


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69980453/viewspace-2724866/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2020-09-28

  • 博文量
    7
  • 访问量
    5384