SQL查询和子查询
GaussDB数据库兼容除分层查询以外的SQL查询和子查询。
| Oracle数据库 | GaussDB数据库 | 差异 |
|---|---|---|
| 创建简单查询 | 支持 | - |
| 分层查询 | 不支持 | - |
| UNION [ALL],INTERSECT,减运算符 | 支持 | - |
| 查询结果排序 | 支持,有差异 | GaussDB查询不包含分组,且目标列同时包含聚集函数和集合返回函数时,不忽略对集合返回函数列的排序。 当查询列涉及类型转换且排序键为原始列名时,GaussDB因转换结果默认别名为原始列名,会按转换后的类型排序;Oracle因转换结果默认别名为转换表达式,仍按原始列的类型排序。两者排序语义不同,可能导致结果集顺序不一致。 |
| Joins | 支持,有差异 | GaussDB只支持和Oracle相同的Join Types,如left、right、self 、natural、full outer join等。不支持In-Memory Join Groups等Join Optimizations方法。 |
| 使用子查询 | 支持 | - |
| 嵌套子查询的解嵌套 | 支持,有差异 | GaussDB不支持显式指定HASH_AJ或MERGE_AJ。 |
| 分布式查询 | 支持,有差异 | GaussDB需要显式DBLINK查询。 |
| 聚集函数嵌套 | 支持 | - |
| 层次查询 | 支持,有差异 |
|
目前xmltable_clause实现的功能与Oracle数据库和PG数据库还存在如下差异,如表2所示。
| GaussDB | PG数据库 | Oracle数据库 |
|---|---|---|
| 在row_expression处及columns_clause中的PATH处使用XPath 1.0表达式。 | 与GaussDB一致。 | 在与row_expression和columns_clause中的PATH对应处使用XQuery 1.0表达式。 |
| 不支持默认命名空间功能。 | 与GaussDB一致。 | 支持默认命名空间功能。 |
| 支持在passing_clause子句中传入单个数据但不可取别名。 | 与GaussDB一致(注意传入数据为XML类型)。 | 支持在对应子句部分传入多个数据且可取别名。 |
| 支持省略passing_clause子句。 | 不支持省略passing_clause子句。 | 支持省略对应子句。 |
| 不支持在passing_clause子句后使用RETURNING SEQUENCE BY REF子句。 | 与GaussDB一致。 | 支持在对应子句后使用RETURNING SEQUENCE BY REF子句。 |
| 不支持在columns_clause子句中使用( SEQUENCE ) BY REF修饰XMLTYPE类型的返回数据。 | 与GaussDB一致。 | 支持在对应子句中使用( SEQUENCE ) BY REF修饰XMLTYPE类型的返回数据。 |
| 在省略columns_clause子句中的PATH部分时,若不使用""将列名包起,在传入XMLTABLE的数据中对应节点的节点名为小写的情况下能正确找到该节点进行后续操作。 | 与GaussDB一致。 | 在省略对应部分时,若不使用""将列名包起,在传入XMLTABLE的数据中对应节点的节点名为大写的情况下能正确找到该节点进行后续操作。 |
| 不支持省略columns_clause子句中列类型的声明。 | 与GaussDB一致。 | 支持省略对应子句中列类型的声明。 |
| 在ORA兼容模式下支持省略columns_clause子句,在PG兼容模式下不支持省略columns_clause子句。 | 不支持省略对应子句。 | 支持省略对应子句。 |
| 在ORA兼容模式下返回数据长度超过类型的typmod时会截断处理,在PG兼容模式下返回数据长度超过类型的typmod时会报错。 | 返回数据长度超过类型的typmod时会报错。 | 返回数据长度超过类型的typmod时会截断处理。 |
示例:
gaussdb=# CREATE DATABASE test DBCOMPATIBILITY = 'ORA';
gaussdb=# \c test
test=# SELECT * FROM XMLTABLE(
test(# XMLNAMESPACES('nspace1' AS "ns1", 'nspace2' AS "ns2"), -- 声明两个XML的命名空间'nspace1'和'nspace2'及对应的别名"ns1"和"ns2"
test(# '/ns1:root/*:child' -- 经row_expression从传入的数据中选取命名空间为'nspace1'的root节点,在选取其下面的所有child节点,忽略child的命名空间;其中ns1为'nspace1'的别名
test(# PASSING xmltype(
test(# '<root xmlns="nspace1">
test'# <child>
test'# <name>peter</name>
test'# <age>11</age>
test'# </child>
test'# <child xmlns="nspace1">
test'# <name>qiqi</name>
test'# <age>12</age>
test'# </child>
test'# <child xmlns="nspace2">
test'# <name>hacker</name>
test'# <age>15</age>
test'# </child>
test'# </root>')
test(# COLUMNS
test(# columns FOR ORDINALITY, -- 该列为行号列
test(# name varchar(10) path 'ns1:name', -- 从row_expression获取的每个child节点中选取命名空间为'nspace1'的name节点,并将节点中的值转换为varchar(10)返回;其中ns1为'nspace1'的别名
test(# age int); -- 从row_expression获取的每个child节点中选取age节点,并将节点中的值转换为int返回;由于第一个child节点没有显式指明命名空间,故跟随父节点root的命名空间,故该列一个值都没有返回
column | name | age
--------+-------+-----
1 | peter |
2 | qiqi |
3 | |
(3 rows)
--切换至默认数据库并删除test数据库(需按照实际情况修改数据库名)。
gaussdb=# \c postgres
gaussdb=# DROP DATABASE test;