计算
弹性云服务器 ECS
Flexus云服务
裸金属服务器 BMS
弹性伸缩 AS
镜像服务 IMS
专属主机 DeH
函数工作流 FunctionGraph
云手机服务器 CPH
Huawei Cloud EulerOS
网络
虚拟私有云 VPC
弹性公网IP EIP
虚拟专用网络 VPN
弹性负载均衡 ELB
NAT网关 NAT
云专线 DC
VPC终端节点 VPCEP
云连接 CC
企业路由器 ER
企业交换机 ESW
全球加速 GA
安全与合规
安全技术与应用
Web应用防火墙 WAF
企业主机安全 HSS
云防火墙 CFW
安全云脑 SecMaster
DDoS防护 AAD
数据加密服务 DEW
数据库安全服务 DBSS
云堡垒机 CBH
数据安全中心 DSC
云证书管理服务 CCM
边缘安全 EdgeSec
威胁检测服务 MTD
CDN与智能边缘
内容分发网络 CDN
CloudPond云服务
智能边缘云 IEC
迁移
主机迁移服务 SMS
对象存储迁移服务 OMS
云数据迁移 CDM
迁移中心 MGC
大数据
MapReduce服务 MRS
数据湖探索 DLI
表格存储服务 CloudTable
云搜索服务 CSS
数据接入服务 DIS
数据仓库服务 GaussDB(DWS)
数据治理中心 DataArts Studio
数据可视化 DLV
数据湖工厂 DLF
湖仓构建 LakeFormation
企业应用
云桌面 Workspace
应用与数据集成平台 ROMA Connect
云解析服务 DNS
专属云
专属计算集群 DCC
IoT物联网
IoT物联网
设备接入 IoTDA
智能边缘平台 IEF
用户服务
账号中心
费用中心
成本中心
资源中心
企业管理
工单管理
国际站常见问题
ICP备案
我的凭证
支持计划
客户运营能力
合作伙伴支持计划
专业服务
区块链
区块链服务 BCS
Web3节点引擎服务 NES
解决方案
SAP
高性能计算 HPC
视频
视频直播 Live
视频点播 VOD
媒体处理 MPC
实时音视频 SparkRTC
数字内容生产线 MetaStudio
存储
对象存储服务 OBS
云硬盘 EVS
云备份 CBR
存储容灾服务 SDRS
高性能弹性文件服务 SFS Turbo
弹性文件服务 SFS
云硬盘备份 VBS
云服务器备份 CSBS
数据快递服务 DES
专属分布式存储服务 DSS
容器
云容器引擎 CCE
容器镜像服务 SWR
应用服务网格 ASM
华为云UCS
云容器实例 CCI
管理与监管
云监控服务 CES
统一身份认证服务 IAM
资源编排服务 RFS
云审计服务 CTS
标签管理服务 TMS
云日志服务 LTS
配置审计 Config
资源访问管理 RAM
消息通知服务 SMN
应用运维管理 AOM
应用性能管理 APM
组织 Organizations
优化顾问 OA
IAM 身份中心
云运维中心 COC
资源治理中心 RGC
应用身份管理服务 OneAccess
数据库
云数据库 RDS
文档数据库服务 DDS
数据管理服务 DAS
数据复制服务 DRS
云数据库 GeminiDB
云数据库 GaussDB
分布式数据库中间件 DDM
数据库和应用迁移 UGO
云数据库 TaurusDB
人工智能
人脸识别服务 FRS
图引擎服务 GES
图像识别 Image
内容审核 Moderation
文字识别 OCR
AI开发平台ModelArts
图像搜索 ImageSearch
对话机器人服务 CBS
华为HiLens
视频智能分析服务 VIAS
语音交互服务 SIS
应用中间件
分布式缓存服务 DCS
API网关 APIG
微服务引擎 CSE
分布式消息服务Kafka版
分布式消息服务RabbitMQ版
分布式消息服务RocketMQ版
多活高可用服务 MAS
事件网格 EG
企业协同
华为云会议 Meeting
云通信
消息&短信 MSGSMS
云生态
合作伙伴中心
云商店
开发者工具
SDK开发指南
API签名指南
Terraform
华为云命令行工具服务 KooCLI
其他
产品价格详情
系统权限
管理控制台
客户关联华为云合作伙伴须知
消息中心
公共问题
开发与运维
应用管理与运维平台 ServiceStage
软件开发生产线 CodeArts
需求管理 CodeArts Req
部署 CodeArts Deploy
性能测试 CodeArts PerfTest
编译构建 CodeArts Build
流水线 CodeArts Pipeline
制品仓库 CodeArts Artifact
测试计划 CodeArts TestPlan
代码检查 CodeArts Check
代码托管 CodeArts Repo
云应用引擎 CAE
开天aPaaS
云消息服务 KooMessage
云手机服务 KooPhone
云空间服务 KooDrive

UNION,CASE和相关构造

更新时间:2024-08-20 GMT+08:00

SQL UNION构造必须把那些可能不太相似的类型匹配起来成为一个结果集。解析算法分别应用于联合查询的每个输出字段。INTERSECT和EXCEPT构造对不相同的类型使用和UNION相同的算法进行解析。CASE、ARRAY、VALUES、GREATEST和LEAST构造也使用同样的算法匹配它的部件表达式并且选择一个结果数据类型。

UNION,CASE和相关构造解析

  • 如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。
  • 如果所有输入都是unknown类型则解析成text类型(字符串类型范畴的首选类型)。否则,忽略unknown输入。
  • 如果输入不属于同一个类型范畴,则失败。(unknown类型除外)
  • 如果输入类型是同一个类型范畴,则选择该类型范畴的首选类型。(例外:union操作会选择第一个分支的类型作为所选类型。)
    说明:

    系统表pg_type中typcategory表示数据类型范畴,typispreferred表示是否是typcategory分类中的首选类型。

  • 把所有输入转换为所选的类型(对于字符串保持原有长度)。如果从给定的输入到所选的类型没有隐式转换则失败。
  • 若输入中含json、txid_snapshot、sys_refcursor或几何类型,则不能进行union。

对于case和coalesce,在TD兼容模式下的处理

  • 如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。
  • 如果所有输入都是unknown类型则解析成text类型。
  • 如果输入字符串(包括unknown,unknown当text来处理)和数字类型,那么解析成字符串类型,如果是其他不同的类型范畴,则报错。
  • 如果输入类型是同一个类型范畴,则选择该类型的优先级较高的类型。
  • 把所有输入转换为所选的类型。如果从给定的输入到所选的类型没有隐式转换则失败。

对于case,在A兼容模式下的处理

decode(expr, search1, result1, search2, result2, ..., defresult); 在设置参数sql_beta_feature = a_style_coerce时,按A兼容模式下的处理,将整个表达式最终的返回值类型定为result1的数据类型,或者与result1同类型范畴的更高精度的数据类型。(例如,numeric与int同属数值类型范畴,但numeric比int精度要高,具有更高优先级)。对于CASE WHEN,A兼容性下与默认行为相同。

  • 如果所有输入都是相同的类型,并且不是unknown类型,那么解析成这种类型。否则,进入后续步骤。
  • 将result1的数据类型置为最终的返回值类型preferType,其所属类型范畴为preferCategory。
  • 依次考虑result2、result3直至defresult的数据类型。如果其类型范畴也是preferCategory,即与result1具有相同的类型范畴,则判断其精度(优先级)是否高于preferType,如果高于,则将preferType更新为更高精度的数据类型;如果其类型范畴不是preferCategory,则判断其数据类型是否可以隐式转换为preferType,不可以则报错。
  • 将最终preferType记录的数据类型作为整个表达式最终的返回值类型;表达式的结果向此类型进行隐式转换。

注1:

为了兼容一种特殊情况,即表示了超大数字的字符类型向数值类型转换的情况,例如select decode(1, 2, 2, '53465465676465454657567678676'),大数超过了bigint、double等的表示范围。所以,当result1的类型范畴为数值类型,且不满足上述"所有输入都是相同的类型"条件时,将返回值的类型直接置为numeric,以兼容此种特殊情况。

注2:

数值类型的优先级排序:numeric>float8>float4>int8>int4>int2>int1

字符类型的优先级排序:text>varchar=nvarchar2>bpchar>char

日期类型的优先级排序:timestamptz>timestamp>smalldatetime>date>abstime>timetz>time

日期跨度类型的优先级排序:interval>tinterval>reltime

注3:

ORA兼容模式,当参数set sql_beta_feature的值设置为'a_style_coerce'时,所支持的隐式类型转换见下图,\代表不需要转换,yes表示支持,空白表示不支持:

示例

示例1:Union中的待定类型解析。这里,unknown类型文本'b'将被解析成text类型。

1
2
3
4
5
6
gaussdb=# SELECT text 'a' AS "text" UNION SELECT 'b';
 text
------
 a
 b
(2 rows)

示例2:简单Union中的类型解析。文本1.2的类型为numeric,而且integer类型的1可以隐含地转换为numeric,因此使用这个类型。

1
2
3
4
5
6
gaussdb=# SELECT 1.2 AS "numeric" UNION SELECT 1;
 numeric
---------
       1
     1.2
(2 rows)

示例3:转置Union中的类型解析。这里,因为类型real不能被隐含转换成integer,但是integer可以隐含转换成real,那么联合的结果类型将是real。

1
2
3
4
5
6
gaussdb=# SELECT 1 AS "real" UNION SELECT CAST('2.2' AS REAL);
 real
------
    1
  2.2
(2 rows)

示例4:TD模式下,coalesce参数输入int和varchar类型,那么解析成varchar类型。A模式下会报错。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
--在A模式下,创建A兼容模式的数据库a_1。
gaussdb=# CREATE DATABASE a_1 dbcompatibility = 'A';

--切换数据库为a_1。
gaussdb=# \c a_1

--创建表t1。
a_1=# CREATE TABLE t1(a int, b varchar(10));

--查看coalesce参数输入int和varchar类型的查询语句的执行计划。                 
a_1=# EXPLAIN SELECT coalesce(a, b) FROM t1;
ERROR:  COALESCE types integer and character varying cannot be matched
LINE 1: EXPLAIN SELECT coalesce(a, b) FROM t1;
                                   ^
CONTEXT:  referenced column: coalesce

--删除表。
a_1=# DROP TABLE t1;

--切换数据库为testdb。
a_1=# \c testdb

--在TD模式下,创建TD兼容模式的数据库td_1。
gaussdb=# CREATE DATABASE td_1 dbcompatibility = 'C';

--切换数据库为td_1。
gaussdb=# \c td_1

--创建表t2。
td_1=# CREATE TABLE t2(a int, b varchar(10));

--查看coalesce参数输入int和varchar类型的查询语句的执行计划。
td_1=# EXPLAIN VERBOSE select coalesce(a, b) from t2;
                                      QUERY PLAN
---------------------------------------------------------------------------------------
 Data Node Scan  (cost=0.00..0.00 rows=0 width=0)
   Output: (COALESCE((t2.a)::character varying, t2.b))
   Node/s: All dbnodes
   Remote query: SELECT COALESCE(a::character varying, b) AS "coalesce" FROM public.t2
(4 rows)

--删除表。
td_1=# DROP TABLE t2;

--切换数据库为testdb。
td_1=# \c testdb

--删除A和TD模式的数据库。
gaussdb=# DROP DATABASE a_1;
gaussdb=# DROP DATABASE td_1;

示例5:ORA模式下,将整个表达式最终的返回值类型定为result1的数据类型,或者与result1同类型范畴的更高精度的数据类型。

--在ORA模式下,创建ORA兼容模式的数据库ora_1。
gaussdb=# CREATE DATABASE ora_1 dbcompatibility = 'A';

--切换数据库为ora_1。
gaussdb=# \c ora_1

--开启Decode兼容性参数。
set sql_beta_feature='a_style_coerce';

--创建表t1。
ora_1=# CREATE TABLE t1(c_int int, c_float8 float8, c_char char(10), c_text text, c_date date);

--插入数据。
ora_1=# INSERT INTO t1 VALUES(1, 2, '3', '4', date '12-10-2010');

--result1类型为char,defresult类型为text,text精度更高,返回值的类型由char更新为text。
ora_1=# SELECT decode(1, 2, c_char, c_text) AS result, pg_typeof(result) FROM t1;
 result | pg_typeof 
--------+-----------
 4      | text
(1 row)

--result1类型为int,属于数值类型范畴,返回值的类型置为numeric。
ora_1=# SELECT decode(1, 2, c_int, c_float8) AS result, pg_typeof(result) FROM t1;
 result | pg_typeof 
--------+-----------
      2 | numeric
(1 row)

--不存在defresult数据类型向result1数据类型之间的隐式转换,报错处理。
ora_1=# SELECT decode(1, 2, c_int, c_date) FROM t1;
ERROR:  CASE types integer and timestamp without time zone cannot be matched
LINE 1: SELECT decode(1, 2, c_int, c_date) FROM t1;
                                   ^
CONTEXT:  referenced column: c_date

--关闭Decode兼容性参数。
set sql_beta_feature='none';

--删除表。
ora_1=# DROP TABLE t1;
DROP TABLE

--切换数据库为testdb。
ora_1=# \c testdb

--删除ORA模式的数据库。
gaussdb=# DROP DATABASE ora_1;
DROP DATABASE

我们使用cookie来确保您的高速浏览体验。继续浏览本站,即表示您同意我们使用cookie。 详情

文档反馈

文档反馈

意见反馈

0/500

标记内容

同时提交标记内容