网络
虚拟私有云 VPC
弹性公网IP EIP
弹性负载均衡 ELB
NAT网关 NAT
云专线 DC
虚拟专用网络 VPN
云连接 CC
VPC终端节点 VPCEP
企业路由器 ER
企业交换机 ESW
全球加速 GA
企业连接 EC
云原生应用网络 ANC
安全与合规
安全技术与应用
Web应用防火墙 WAF
企业主机安全 HSS
云防火墙 CFW
安全云脑 SecMaster
DDoS防护 AAD
数据加密服务 DEW
数据库安全服务 DBSS
云堡垒机 CBH
数据安全中心 DSC
云证书管理服务 CCM
威胁检测服务 MTD
认证测试中心 CTC
边缘安全 EdgeSec
应用中间件
微服务引擎 CSE
分布式消息服务Kafka版
分布式消息服务RabbitMQ版
分布式消息服务RocketMQ版
API网关 APIG
分布式缓存服务 DCS
多活高可用服务 MAS
事件网格 EG
管理与监管
统一身份认证服务 IAM
消息通知服务 SMN
云监控服务 CES
应用运维管理 AOM
应用性能管理 APM
云日志服务 LTS
云审计服务 CTS
标签管理服务 TMS
配置审计 Config
应用身份管理服务 OneAccess
资源访问管理 RAM
组织 Organizations
资源编排服务 RFS
优化顾问 OA
IAM 身份中心
云运维中心 COC
资源治理中心 RGC
解决方案
高性能计算 HPC
SAP
混合云灾备
开天工业工作台 MIW
Haydn解决方案工厂
数字化诊断治理专家服务
云生态
云商店
合作伙伴中心
华为云开发者学堂
华为云慧通差旅
开发与运维
软件开发生产线 CodeArts
需求管理 CodeArts Req
流水线 CodeArts Pipeline
代码检查 CodeArts Check
编译构建 CodeArts Build
部署 CodeArts Deploy
测试计划 CodeArts TestPlan
制品仓库 CodeArts Artifact
移动应用测试 MobileAPPTest
CodeArts IDE Online
开源镜像站 Mirrors
性能测试 CodeArts PerfTest
应用管理与运维平台 ServiceStage
云应用引擎 CAE
开源治理服务 CodeArts Governance
华为云Astro轻应用
CodeArts IDE
Astro工作流 AstroFlow
代码托管 CodeArts Repo
漏洞管理服务 CodeArts Inspector
联接 CodeArtsLink
软件建模 CodeArts Modeling
Astro企业应用 AstroPro
CodeArts 盘古助手
华为云Astro大屏应用
计算
弹性云服务器 ECS
Flexus云服务
裸金属服务器 BMS
云手机服务器 CPH
专属主机 DeH
弹性伸缩 AS
镜像服务 IMS
函数工作流 FunctionGraph
云耀云服务器(旧版)
VR云渲游平台 CVR
Huawei Cloud EulerOS
云化数据中心 CloudDC
网络
虚拟私有云 VPC
弹性公网IP EIP
弹性负载均衡 ELB
NAT网关 NAT
云专线 DC
虚拟专用网络 VPN
云连接 CC
VPC终端节点 VPCEP
企业路由器 ER
企业交换机 ESW
全球加速 GA
企业连接 EC
云原生应用网络 ANC
CDN与智能边缘
内容分发网络 CDN
智能边缘云 IEC
智能边缘平台 IEF
CloudPond云服务
安全与合规
安全技术与应用
Web应用防火墙 WAF
企业主机安全 HSS
云防火墙 CFW
安全云脑 SecMaster
DDoS防护 AAD
数据加密服务 DEW
数据库安全服务 DBSS
云堡垒机 CBH
数据安全中心 DSC
云证书管理服务 CCM
威胁检测服务 MTD
认证测试中心 CTC
边缘安全 EdgeSec
大数据
MapReduce服务 MRS
数据湖探索 DLI
表格存储服务 CloudTable
可信智能计算服务 TICS
推荐系统 RES
云搜索服务 CSS
数据可视化 DLV
数据接入服务 DIS
数据仓库服务 GaussDB(DWS)
数据治理中心 DataArts Studio
湖仓构建 LakeFormation
智能数据洞察 DataArts Insight
应用中间件
微服务引擎 CSE
分布式消息服务Kafka版
分布式消息服务RabbitMQ版
分布式消息服务RocketMQ版
API网关 APIG
分布式缓存服务 DCS
多活高可用服务 MAS
事件网格 EG
开天aPaaS
应用平台 AppStage
开天企业工作台 MSSE
开天集成工作台 MSSI
API中心 API Hub
云消息服务 KooMessage
交换数据空间 EDS
云地图服务 KooMap
云手机服务 KooPhone
组织成员账号 OrgID
云空间服务 KooDrive
管理与监管
统一身份认证服务 IAM
消息通知服务 SMN
云监控服务 CES
应用运维管理 AOM
应用性能管理 APM
云日志服务 LTS
云审计服务 CTS
标签管理服务 TMS
配置审计 Config
应用身份管理服务 OneAccess
资源访问管理 RAM
组织 Organizations
资源编排服务 RFS
优化顾问 OA
IAM 身份中心
云运维中心 COC
资源治理中心 RGC
区块链
区块链服务 BCS
数字资产链 DAC
华为云区块链引擎服务 HBS
解决方案
高性能计算 HPC
SAP
混合云灾备
开天工业工作台 MIW
Haydn解决方案工厂
数字化诊断治理专家服务
价格
成本优化最佳实践
专属云商业逻辑
云生态
云商店
合作伙伴中心
华为云开发者学堂
华为云慧通差旅
其他
管理控制台
消息中心
产品价格详情
系统权限
客户关联华为云合作伙伴须知
公共问题
宽限期保留期
奖励推广计划
活动
云服务信任体系能力说明
开发与运维
软件开发生产线 CodeArts
需求管理 CodeArts Req
流水线 CodeArts Pipeline
代码检查 CodeArts Check
编译构建 CodeArts Build
部署 CodeArts Deploy
测试计划 CodeArts TestPlan
制品仓库 CodeArts Artifact
移动应用测试 MobileAPPTest
CodeArts IDE Online
开源镜像站 Mirrors
性能测试 CodeArts PerfTest
应用管理与运维平台 ServiceStage
云应用引擎 CAE
开源治理服务 CodeArts Governance
华为云Astro轻应用
CodeArts IDE
Astro工作流 AstroFlow
代码托管 CodeArts Repo
漏洞管理服务 CodeArts Inspector
联接 CodeArtsLink
软件建模 CodeArts Modeling
Astro企业应用 AstroPro
CodeArts 盘古助手
华为云Astro大屏应用
存储
对象存储服务 OBS
云硬盘 EVS
云备份 CBR
高性能弹性文件服务 SFS Turbo
弹性文件服务 SFS
存储容灾服务 SDRS
云硬盘备份 VBS
云服务器备份 CSBS
数据快递服务 DES
云存储网关 CSG
专属分布式存储服务 DSS
数据工坊 DWR
地图数据 MapDS
键值存储服务 KVS
容器
云容器引擎 CCE
云容器实例 CCI
容器镜像服务 SWR
云原生服务中心 OSC
应用服务网格 ASM
华为云UCS
数据库
云数据库 RDS
数据复制服务 DRS
文档数据库服务 DDS
分布式数据库中间件 DDM
云数据库 GaussDB
云数据库 GeminiDB
数据管理服务 DAS
数据库和应用迁移 UGO
云数据库 TaurusDB
人工智能
AI开发平台ModelArts
华为HiLens
图引擎服务 GES
图像识别 Image
文字识别 OCR
自然语言处理 NLP
内容审核 Moderation
图像搜索 ImageSearch
医疗智能体 EIHealth
企业级AI应用开发专业套件 ModelArts Pro
人脸识别服务 FRS
对话机器人服务 CBS
语音交互服务 SIS
人证核身服务 IVS
视频智能分析服务 VIAS
城市智能体
自动驾驶云服务 Octopus
盘古大模型 PanguLargeModels
IoT物联网
设备接入 IoTDA
全球SIM联接 GSL
IoT数据分析 IoTA
路网数字化服务 DRIS
IoT边缘 IoTEdge
设备发放 IoTDP
企业应用
域名注册服务 Domains
云解析服务 DNS
企业门户 EWP
ICP备案
商标注册
华为云WeLink
华为云会议 Meeting
隐私保护通话 PrivateNumber
语音通话 VoiceCall
消息&短信 MSGSMS
云管理网络
SD-WAN 云服务
边缘数据中心管理 EDCM
云桌面 Workspace
应用与数据集成平台 ROMA Connect
ROMA资产中心 ROMA Exchange
API全生命周期管理 ROMA API
政企自服务管理 ESM
视频
实时音视频 SparkRTC
视频直播 Live
视频点播 VOD
媒体处理 MPC
视频接入服务 VIS
数字内容生产线 MetaStudio
迁移
主机迁移服务 SMS
对象存储迁移服务 OMS
云数据迁移 CDM
迁移中心 MGC
专属云
专属计算集群 DCC
开发者工具
SDK开发指南
API签名指南
DevStar
华为云命令行工具服务 KooCLI
Huawei Cloud Toolkit
CodeArts API
云化转型
云架构中心
云采用框架
用户服务
账号中心
费用中心
成本中心
资源中心
企业管理
工单管理
客户运营能力
国际站常见问题
支持计划
专业服务
合作伙伴支持计划
我的凭证
华为云公共事业服务云平台
工业软件
工业数字模型驱动引擎
硬件开发工具链平台云服务
工业数据转换引擎云服务

SELECT

更新时间:2025-01-20 GMT+08:00
分享

功能描述

SELECT用于从表或视图中取出数据。

SELECT语句就像叠加在数据库表上的过滤器,利用SQL关键字从数据表中过滤出用户需要的数据。

注意事项

  • 表的所有者、拥有表SELECT权限的用户或拥有SELECT ANY TABLE权限的用户,有权限读取表或视图中数据,当三权分立开关关闭时,系统管理员默认拥有此权限。
  • SELECT支持普通表的JOIN,不支持普通表和GDS外表的JOIN。即SELECT语句中不能同时出现普通表和GDS外表。
  • 必须对每个在SELECT命令中使用的字段有SELECT权限。
  • 使用FOR UPDATE或FOR SHARE除了SELECT权限外还要求UPDATE权限。

语法格式

查询数据:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
[ WITH [ RECURSIVE ] with_query [, ...] ]
SELECT [/*+ plan_hint */] [ ALL | DISTINCT [ ON ( expression [, ...] ) ] ]
    { * | {expression [ [ AS ] output_name ]} [, ...] }
    [ FROM from_item [, ...] ]
    [ WHERE condition ]
    [ [ START WITH condition ] CONNECT BY [NOCYCLE] 
    condition [ ORDER SIBLINGS BY expression ] ]
    [ GROUP BY grouping_element [, ...] ]
    [ HAVING condition [, ...] ]
    [ WINDOW {window_name AS ( window_definition )} [, ...] ]
    [ { UNION | INTERSECT | EXCEPT | MINUS } [ ALL | DISTINCT ] select ]
    [ ORDER BY {expression [ [ ASC | DESC | USING operator ] | nlssort_expression_clause ] [ NULLS { FIRST | LAST } ]} [, ...] ]
    [ LIMIT { [offset,] count | ALL } ]
    [ OFFSET start [ ROW | ROWS ] ]
    [ FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY ]
    [ {FOR { UPDATE | SHARE } [ OF table_name [, ...] ] [ NOWAIT | WAIT n | SKIP LOCKED ]} [...] ];
说明:

condition和expression中可以使用targetlist中表达式的别名。

  • 只能同一层引用。
  • 只能引用targetlist中的别名。
  • 只能是后面的表达式引用前面的表达式。
  • 不能包含volatile函数。
  • 不能包含Window function函数。
  • 不支持在JOIN ON条件中引用别名。
  • targetlist中有多个要应用的别名则报错。
须知:

缓存SELECT语句计划的场景下,WHERE IN候选子集不易过大,建议条件个数不要超过100,防止引发动态内存过高问题:

  • WHERE IN候选子集过大时,生成计划的内存占用会增大。
  • 当拼接SQL构造的WHERE IN子集不同,缓存计划的SQL模板无法复用。会生成大量不同的计划且计划无法共享 ,占用大量内存。
  • 其中子查询with_query为:
    1
    2
    with_query_name [ ( column_name [, ...] ) ]
        AS [ [ NOT ] MATERIALIZED ] ( {select | values | insert | update | delete} )
    
  • 其中指定查询源from_item为:
     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    {[ ONLY ] table_name [ * ] [ partition_clause ] [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
    [ TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ] ]
    [ TIMECAPSULE {TIMESTAMP | CSN} expression ]
    |( select ) [ AS ] alias [ ( column_alias [, ...] ) ]
    |with_query_name [ [ AS ] alias [ ( column_alias [, ...] ) ] ]
    |function_name ( [ argument [, ...] ] ) [ AS ] alias [ ( column_alias [, ...] | column_definition [, ...] ) ]
    |function_name ( [ argument [, ...] ] ) AS ( column_definition [, ...] )
    |xmltable_clause
    |from_item unpivot_clause
    |from_item pivot_clause
    |from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]}
    
  • 其中GROUP BY子句为:
    1
    2
    3
    4
    5
    6
    ( )
    | expression
    | ( expression [, ...] )
    | ROLLUP ( { expression | ( expression [, ...] ) } [, ...] )
    | CUBE ( { expression | ( expression [, ...] ) } [, ...] )
    | GROUPING SETS ( grouping_element [, ...] )
    
  • from_item中指定分区partition_clause为:
    1
    PARTITION { ( partition_name [, ...] ) | FOR ( partition_value [, ...] ) }
    
    说明:
    • 指定分区只适合分区表。
    • PARTITION指定多个分区名时,可以存在相同的分区名,最终分区范围取其并集。
  • 其中设置排序方式nlssort_expression_clause为:
    1
    NLSSORT ( column_name, ' NLS_SORT = { SCHINESE_PINYIN_M | generic_m_ci } ' )
    

    第二个参数可选generic_m_ci,仅支持纯英文不区分大小写排序。

  • 简化版查询语法,功能相当于SELECT * FROM table_name。
    1
    TABLE { ONLY {(table_name)| table_name} | table_name [ * ]};
    
  • 其中xmltable_clause为:
    XMLTABLE(
    xmlnamespaces_clause
    row_expression
    passing_clause
    columns_clause
    )
    • xmlnamespaces_clause为:
      [
          XMLNAMESPACES(
          {string AS identifier }
          |
          { DEFAULT string }
          [, { string AS identifier } | { DEFAULT string } ]...
          ),
      ]
    • passing_clause为:
      PASSING [BY { REF | VALUE }] document_expression [BY { REF | VALUE }]
    • columns_clause为:
      [
          COLUMNS
          name { type [PATH column_expression] [DEFAULT default_expression] [NOT NULL | NULL] | FOR ORDINALITY }
          [, ...]
      ]

参数说明

  • WITH [ RECURSIVE ] with_query [, ...]

    用于声明一个或多个可以在主查询中通过名称引用的子查询,相当于临时表。这种子查询语句结构称为CTE(Common Table Expression)结构,应用这种结构时,执行计划中将存在CTE SCAN的内容。

    如果声明了RECURSIVE,那么允许SELECT子查询通过名称引用它自己。

    其中with_query的详细格式为:with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ] ( {select | values | insert | update | delete} )

    • with_query_name指定子查询生成的结果集名称,在查询中可使用该名称访问子查询的结果集。
    • column_name指定子查询结果集中显示的列名。
    • 每个子查询可以是SELECT、VALUES、INSERT、UPDATE或DELETE语句。
    • RECURSIVE只能出现在WITH后面,多个CTE的情况下,只需要在第一个CTE处声明RECURSIVE。
    • 用户可以使用MATERIALIZED / NOT MATERIALIZED对CTE进行修饰。对于Stream计划,目前仅支持内联执行一种方式,此时该语法不生效。
      • 如果声明为MATERIALIZED,WITH查询将被物化,生成一个子查询结果集的复制,在引用处直接查询该复制,因此WITH子查询无法和主干SELECT语句进行联合优化(如谓词下推、等价类传递等)。当使用NOT MATERIALIZED进行修饰时,如果WITH查询语义上可以作为子查询内联执行,则可以进行上述优化。
      • 如果用户没有显式声明物化属性则遵守以下规则:如果CTE只在所属SELECT主干中被引用一次,且语义上支持内联执行,则会被改写为子查询内联执行,否则以CTE Scan的方式物化执行。
  • plan_hint子句

    以/*+ */的形式在SELECT关键字后,用于对SELECT对应语句块生成的计划进行hint调优,详细用法请参见章节使用Plan Hint进行调优。每条语句中只有第一个/*+ plan_hint */注释块会作为hint生效,里面可以写多条hint。

  • ALL

    声明返回所有符合条件的行,是默认行为,可以省略该关键字。

  • DISTINCT [ ON ( expression [, ...] ) ]

    从SELECT的结果集中删除所有重复的行,使结果集中的每行都是唯一的。

    ON ( expression [, ...] ) 只保留那些在给出的表达式上运算出相同结果的行集合中的第一行。

    须知:

    DISTINCT ON表达式是使用与ORDER BY相同的规则进行解释的。除非使用了ORDER BY来保证需要的行首先出现,否则,"第一行"是不可预测的。

  • SELECT列表

    指定查询表中列名,可以是部分列或者是全部(使用通配符*表示)。

    通过使用子句AS output_name可以为输出字段取个别名,这个别名通常用于输出字段的显示。支持关键字name、value和type作为列别名。

    列名可以用下面几种形式表达:

    • 手动输入列名,多个列之间用英文逗号“,”分隔。
    • 可以是FROM子句里面计算出来的字段。
  • FROM子句

    为SELECT声明一个或多个源表。

    FROM子句涉及的元素如下所示。

    • table_name

      表名或视图名,名称前可加上模式名,如:schema_name.table_name。

      说明:

      支持使用DATABASE LINK方式对远端表、同义词进行操作,使用方式详情请见DATABASE LINK

    • alias

      给表或复杂的表引用起一个临时的表别名,以便被其余的查询引用。

      别名用于缩写或者在自连接中消除歧义。如果提供了别名,它就会完全代替表的实际名称。

      须知:

      当为JOIN产生的表joined_table指定别名时,如果joined_table被()包裹,即(joined_table),非保留关键字UNPIVOT和PIVOT不允许作为别名使用。

    • TABLESAMPLE sampling_method ( argument [, ...] ) [ REPEATABLE ( seed ) ]

      table_name之后的TABLESAMPLE子句表示应该用指定的sampling_method来检索表中行的子集。

      可选的REPEATABLE子句指定一个用于产生采样方法中随机数的种子数。种子值可以是任何非空常量值。如果查询时表没有被更改,指定相同种子和argument值的两个查询将会选择该表相同的采样。但是不同的种子值通常将会产生不同的采样。如果没有给出REPEATABLE,则会基于一个系统产生的种子为每一个查询选择一个新的随机采样。

    • TIMECAPSULE { TIMESTAMP | CSN } expression

      查询指定CSN点或者指定时间点表的内容。

      目前不支持闪回查询的表:系统表、DFS表、全局临时表、本地临时表、UNLOGGED表、视图、序列表、hash bucket表、共享表、继承表。

      • TIMECAPSULE TIMESTAMP

        关键字,闪回查询的标识,根据date日期,闪回查找指定时间点的结果集。date日期必须是一个过去有效的时间戳。

      • TIMECAPSULE CSN

        关键字,闪回查询的标识,根据表的CSN闪回查询指定CSN点的结果集。其中CSN可从gs_txn_snapshot记录的snpcsn号查得。

      • expression

        常量、函数或SQL表达式。

        说明:
        • 闪回查询不能跨越影响表结构或物理存储的语句,否则会报错。即闪回点和当前点之间,如果执行过修改表结构或影响物理存储的语句(TRUNCATE、DDL、DCL、VACUUM FULL),则闪回失败。执行过DDL的表进行闪回操作报错:“ERROR:The table definition of %s has been changed.”。涉及namespace、表名改变等操作的DDL执行闪回操作报错:“ERROR: recycle object %s desired does not exist.”。
        • 闪回查询支持PCR类型的UBTree索引进行索引扫描;如果没有创建PCR类型的UBTree索引,则闪回查询只能通过seqScan进行全表扫描。
        • 闪回点过旧时,因闪回版本被回收等导致无法获取旧版本会导致闪回失败,报错:Restore point too old。
        • 通过时间方式指定闪回点,闪回数据和实际时间点最多偏差为3秒。
        • 对表执行TRUNCATE之后,再进行闪回查询或者闪回表操作。通过时间点进行的闪回操作会报错:Snapshot too old。通过CSN进行的闪回操作会找不到数据,或者报错:Snapshot too old。
        • GTM-Free场景各节点使用本地csn,没有全局统一csn号,暂不支持使用CSN方式进行闪回操作。
    • column_alias

      列别名。

    • PARTITION

      查询分区表的某个分区的数据。

    • partition_name

      分区名。

    • partition_value

      指定的分区键值。在创建分区表时,如果指定了多个分区键,可以通过PARTITION FOR子句指定的这一组分区键的值,唯一确定一个分区。

    • subquery

      FROM子句中可以出现子查询,创建一个临时表保存子查询的输出。

    • with_query_name

      WITH子句同样可以作为FROM子句的源,可以通过WITH查询的名称对其进行引用。

    • function_name

      函数名称。函数调用也可以出现在FROM子句中。

    • join_type

      有5种类型,如下所示:

      • [ INNER ] JOIN

        一个JOIN子句组合两个FROM项。可使用圆括弧以决定嵌套的顺序。如果没有圆括弧,JOIN从左向右嵌套。

      • LEFT [ OUTER ] JOIN

        返回笛卡尔积中所有符合连接条件的行,再加上左表中通过连接条件没有匹配到右表行的那些行。这样,左边的行将扩展为生成表的全长,方法是在那些右表对应的字段位置填上NULL。请注意,只在计算匹配的时候,才使用JOIN子句的条件,外层的条件是在计算完毕之后施加的。

      • RIGHT [ OUTER ] JOIN

        返回所有内连接的结果行,加上每个不匹配的右边行(左边用NULL扩展)。

        这只是一个符号上的方便,因为总是可以把它转换成一个LEFT OUTER JOIN,只要把左边和右边的输入互换位置即可。

      • FULL [ OUTER ] JOIN

        返回所有内连接的结果行,加上每个不匹配的左边行(右边用NULL扩展),再加上每个不匹配的右边行(左边用NULL扩展)。

      • CROSS JOIN

        CROSS JOIN等效于INNER JOIN ON(TRUE) ,即没有被条件删除的行。这种连接类型只是符号上的方便,因为它们与简单的FROM和WHERE的效果相同。

        说明:

        必须为INNER和OUTER连接类型声明一个连接条件,即NATURAL ON、join_condition、USING (join_column [, ...]) 之一。但是它们不能出现在CROSS JOIN中。

      其中CROSS JOIN和INNER JOIN生成一个简单的笛卡尔积,和在FROM的顶层列出两个项的结果相同。

    • ON join_condition

      连接条件,用于限定连接中的哪些行是匹配的。如:ON left_table.a = right_table.a。不建议使用int等数值类型作为join_condition,因为int等数值类型可以隐式转换为bool值(非0值隐式转换为true,0转换为false),可能导致非预期的结果。

    • USING(join_column[,...])

      ON left_table.a = right_table.a AND left_table.b = right_table.b ... 的简写。要求对应的列必须同名。

    • NATURAL

      NATURAL是具有相同名称的两个表的所有列的USING列表的简写。

    • from item

      用于连接的查询源对象的名称。

    • xmltable_clause

      xmltable_clause仅支持在ORA兼容模式和PG兼容模式下使用。xmltable_clause基于给定的XMLTYPE(在ORA兼容模式下)或XML(在PG兼容模式下)类型的数据产生一个虚拟表。

      • xmlnamespaces_clause

        可选的xmlnamespaces_clause是一个以XMLNAMESPACES开始,后跟以英文逗号分隔的XML命名空间声明的子句。其中string为英文单引号作为边界符的命名空间全称,identifier为英文双引号作为边界符的命名空间别名,且别名可以在row_expression及columns_clause中使用。当前版本不支持使用DEFAULT声明默认的命名空间。

      • row_expression

        所需的row_expression为英文单引号作为边界符的XPath 1.0表达式。将后续passing_clause中的document_expression作为其上下文,得到一组XML节点。这些节点经后续的columns_clause处理生成虚拟表的每一行。

      • passing_clause

        所需的passing_clause以PASSING开始,其中的document_expression为传入XMLTABLE中被处理的XMLTYPE(在ORA兼容模式下)或XML(在PG兼容模式下)类型的数据,目前仅支持单根数据。在ORA兼容模式下,无论使用第一处还是第二处的BY VALUE或BY REF都会报错;在PG兼容模式下,虽然可以识别接收第一处和第二处的BY VALUE或BY REF,但并未做功能上的处理。

      • columns_clause

        可选的columns_clause用来指明将在虚拟表中生成的列所需的相关信息。

        name:为列的名称。

        type:为列的类型。

        PATH:可选的PATH部分的column_expression为XPath 1.0的表达式,由row_expression得到的节点集中的某个节点作为其上下文,经其处理得到该节点生成的行数据中对应列的值所需的数据,在将其转换为type类型的结果时,存在隐式转换。若没有给出PATH部分,则name会被当作column_expression。

        DEFAULT:可选的DEFAULT部分的default_expression为一个表达式,若经column_expression处理后该列得到NULL值,会将计算default_expression得到的结果用于生成该列的值,注意default_expression会在需要的时候才进行计算,若表达式为稳定的,则在需要的时候只会计算一次。

        NOT NULL | NULL:在PG兼容模式下,可选的NOT NULL或NULL用来说明该列是否可为NULL值,若列值与指定的选项不符则会报错。

        FOR ORDINALITY:说明该列为行号列,从1开始为生成的行填充行号,最多只能有一个列被标记为FOR ORDINALITY。

        在ORA兼容模式下可省略columns_clause,当省略columns_clause后,会在内部生成默认的columns_clause:COLUMNS column_value XMLTYPE PATH '.'来用于后续的处理。在PG兼容模式下不可省略columns_clause。

      须知:

      目前xmltable_clause存在以下约束:

      • 其中涉及的XPath表达式均为XPath 1.0。
      • 目前不支持在column_expression使用形如'..'的XPath表达式。
      • 经过column_expression得到的数据在转换为type类型的数据时,在ORA兼容模式下,若得到的数据过长,超过类型的typmod,会截断处理。目前仅对CHAR、CHARACTER、NCHAR、BPCHAR、VARCHAR、CHARACTER VARYING、VARCHAR2、NVARCHAR2数据类型(包括附带(n)形式)的typmod大于0时,过长的数据会进行截断处理。在PG兼容模式下,会报错处理。
      • 目前支持传入的XMLTYPE(在ORA兼容模式下)或XML(在PG兼容模式下)类型数据的最大值为1GB。
      • 从不支持XMLTABLE的版本升级到支持XMLTABLE的版本时,在升级观察期期间,不可使用XMLTABLE语法。
      • 仅在ORA兼容模式下支持XPath中存在如下表达:*:nodename,其中nodename为节点名称,该种表达表示选取nodename节点时忽略其命名空间。
      • 非保留关键字XMLTABLE不能作为Functions as Table Sources类型函数的函数名称。
      说明:

      在输入非良构的XMLTYPE(在ORA兼容模式下)类型数据时,会把与非良构部分同级的,在非良构部分之后的用于节点间控制书写格式的空格和回车字符当作文本节点解析,如下面文本中node2节点的结束标签与node3节点的开始标签之间的空格和回车即会被当作文本节点解析,此与ORA数据库不一致,使用时请注意。

      输入情况:

      <root>
      <node1>node1</node1>
      malform
      <node2>node2</node2>
      <node3>node3</node3>
      </root>

      实际情况:

      <root><node1>node1</node1>
      malform
      <node2>node2</node2>
      <node3>node3</node3>
      </root>

      目前xmltable_clause实现的功能与ORA数据库和PG数据库还存在如下差异,使用时请注意,详见表1

      表1 GaussDB Kernel与ORA数据库和PG数据库对比

      GaussDB Kernel数据库

      PG数据库

      ORA数据库

      在row_expression处及columns_clause中的PATH处使用XPath 1.0表达式。

      GaussDB Kernel一致。

      在与row_expression和columns_clause中的PATH对应处使用XQuery 1.0表达式。

      不支持默认命名空间功能。

      GaussDB Kernel一致。

      支持默认命名空间功能。

      支持在passing_clause子句中传入单个数据但不可取别名。

      GaussDB Kernel一致(注意传入数据为XML类型)。

      支持在对应子句部分传入多个数据且可取别名。

      不支持省略passing_clause子句。

      GaussDB Kernel一致。

      支持省略对应子句。

      不支持在passing_clause子句后使用RETURNING SEQUENCE BY REF子句。

      GaussDB Kernel一致。

      支持在对应子句后使用RETURNING SEQUENCE BY REF子句。

      不支持在columns_clause子句中使用( SEQUENCE ) BY REF修饰XMLTYPE类型的返回数据。

      GaussDB Kernel一致。

      支持在对应子句中使用( SEQUENCE ) BY REF修饰XMLTYPE类型的返回数据。

      在省略columns_clause子句中的PATH部分时,若不使用""将列名包起,在传入XMLTABLE的数据中对应节点的节点名为小写的情况下能正确找到该节点进行后续操作。

      GaussDB Kernel一致。

      在省略对应部分时,若不使用""将列名包起,在传入XMLTABLE的数据中对应节点的节点名为大写的情况下能正确找到该节点进行后续操作。

      不支持省略columns_clause子句中列类型的声明。

      GaussDB Kernel一致。

      支持省略对应子句中列类型的声明。

      在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;
    • unpivot_clause
      unpivot_clause可将列转置为行,其对应语法格式为:
       UNPIVOT [ {INCLUDE | EXCLUDE} NULLS ]
          (   
              unpivot_col_clause
              unpivot_for_clause
              unpivot_in_clause
          )
      • {INCLUDE | EXCLUDE} NULLS

        该子句用于控制转置后的结果是否包含存在NULL值的行,INCLUDE NULLS将使得结果包含存在NULL值的行,而EXCLUDE NULLS将从结果集中过滤掉这些行数据。如果忽略该子句,unpivot操作默认会从结果集中剔除存在NULL值的行。

      • unpivot_col_clause为:
        unpivot_col_element 

        unpivot_col_element指定了输出的列名,这些列会保存待转置列的列值。

      • unpivot_col_element为:
        { column | ( column [, column]... ) }

        unpivot_col_element有两种形式:column;( column [, column]... )。

      • unpivot_for_clause为:
        FOR { unpivot_col_element }

        unpivot_for_clause中的unpivot_col_element用于指定输出的列名,这些列会保存待转置列的列名或别名。

      • unpivot_in_clause为:
        IN ( unpivot_in_element [,unpivot_in_element...] )

        unpivot_in_clause指定了待转置列,这些列的列名和列值将保存在之前指定的输出列中。

        unpivot_in_element为:
        { unpivot_col_element }[  AS { unpivot_alias_element } ]

        unpivot_col_element为指定的待转置列,若采用( column [, column]... )形式指定待转置列,( column [, column]... )中所有的column列名将通过下划线 "_" 进行拼接,并保存在输出列中。如,IN ((col1, col2)) 将会生成列名 "col1_col2",并保存在unpivot_for_clause指定的输出列中。此外,AS关键字可为待转置列指定别名,一旦指定别名,输出列中将保存别名而不再保存待转置列的列名。

      • unpivot_alias_element为:
        { alias | ( alias [, alias]... )}

        与unpivot_col_element类似,unpivot_alias_element也有两种形式。其中,alias为指定的别名。

      须知:

      目前unpivot_clause存在如下约束:

      • 仅支持在ORA兼容模式下使用。
      • unpivot_clause子句内不支持与hint配合使用。
      • 对于unpivot_col_clause,其unpivot_col_element指定的输出列数目需与unpivot_in_clause中unpivot_col_element的列数目相同。
      • 对于unpivot_for_clause,其unpivot_col_element指定的输出列数目需与unpivot_in_clause中unpivot_alias_element的别名数目相同。
      • 对于unpivot_in_clause,别名必须为常量,或者可以转换为常量的表达式。
      • 对于unpivot_in_clause,常量表达式支持的函数只能是不可变(IMMUTABLE)函数。
      • 对于unpivot_in_clause的所有unpivot_col_element而言,如果这些unpivot_col_element相同位置的column类型存在差异,则unpivot会尝试进行类型转换,以将这些转置列的列值转换为公共类型。类似地,对于所有unpivot_alias_element而言,如果这些unpivot_alias_element相同位置的alias类型存在差异,unpivot也会进行类似的类型转换。

        如,假定存在"IN (col1, col2)"形式的unpivot_in_clause,其中col1为int类型,而col2为float类型,则unpivot在计算过程中会尝试将col1的列值转为公共类型float。

    • pivot_clause

      pivot_clause可将行转置为列,其对应语法格式为:

      PIVOT [ XML ]
      ( aggregate_function ( expr ) [[AS] alias ]
          [, aggregate_function ( expr ) [[AS] alias ] ]...
          pivot_for_clause
          pivot_in_clause
      )
      • aggregate_function ( expr ) [[AS] alias ]

        aggregate_function针对给定的表达式进行聚合计算,计算结果将保存在pivot_in_clause指定的输出列中。[AS] alias(AS关键字可省略)可为aggregate_function指定别名,别名将以 "_别名" 格式附加在pivot_in_clause指定的输出列名后。

      • pivot_for_clause为:
        FOR { column
            | ( column [, column]... )
            }

        pivot_for_clause指定了待转置行,column表示待转置行的某一列。

      • pivot_in_clause为:
        IN ( { { { expr
                 | ( expr [, expr]... )
                 } [ [AS] alias]
               }...
             }
          )

        pivot_in_clause指定了输出结果的列名,列名可由一个expr或多个expr构成,如,(expr1, expr2)。当列名由多个expr构成时,这些expr将按顺序通过下划线 "_" 进行连接,即(expr1, expr2)对应的输出列名为 "expr1_expr2"。除了生成输出列名外,这些expr还决定着聚合函数触发时机,当待转置行的行值与这些expr的值相同时,pivot将进行聚合函数aggregate_function的计算,并将计算结果保存在列名由这些expr构成的输出列中。假定expr1为1,expr2为2,对于行"1 2",pivot将进行aggregate_function的计算,对于行"1 1",则不会触发计算。

      须知:

      目前pivot_clause存在如下约束:

      • 仅支持在ORA兼容模式下使用。
      • pivot_clause子句内不支持与hint配合使用。
      • 当指定多于一个aggregate_function时,最多允许一个aggregate_function没有别名,其余aggregate_function均需指定别名。
      • XML只支持语法不支持功能。
      • pivot_in_clause中的expr可以是常量,或者是可以转换为常量的表达式。若不是一元表达式,则需为expr指定别名。
      • 对于pivot_in_clause中的expr,常量表达式支持的函数只能是不可变(IMMUTABLE)函数。
      • 对于pivot_in_clause中的expr,当通过as为其指定别名时,非保留关键字可作为别名使用,否则不能。
      • 输出列的列名长度限制为63,超出将报错。
  • WHERE子句

    WHERE子句构成一个行选择表达式,用来缩小SELECT查询的范围。condition是返回值为布尔型的任意表达式,任何不满足该条件的行都不会被检索。不建议使用int等数值类型作为condition,因为int等数值类型可以隐式转换为bool值(非0值隐式转换为true,0转换为false),可能导致非预期的结果。

    WHERE子句中可以通过指定"(+)"操作符的方法将表的连接关系转换为外连接。但是不建议用户使用这种用法,因为这并不是SQL的标准语法,在做平台迁移的时候可能面临语法兼容性的问题。同时,使用"(+)"有很多限制:

    1. "(+)"只能出现在where子句中。
    2. 如果from子句中已经有指定表连接关系,那么不能再在where子句中使用"(+)"。
    3. "(+)"只能作用在表或者视图的列上,不能作用在表达式上。
    4. 如果表A和表B有多个连接条件,那么必须在所有的连接条件中指定"(+)",否则"(+)"将不会生效,表连接会转化成内连接,并且不给出任何提示信息。
    5. "(+)"作用的连接条件中的表不能跨查询或者子查询。如果"(+)"作用的表,不在当前查询或者子查询的from子句中,则会报错。如果"(+)"作用的对端的表不存在,则不报错,同时连接关系会转化为内连接。
    6. "(+)"作用的表达式不能直接通过"OR"连接。
    7. 如果"(+)"作用的列是和一个常量的比较关系, 那么这个表达式会成为JOIN条件的一部分。
    8. 同一个表不能对应多个外表。
    9. "(+)"只能出现"比较表达式"、"NOT表达式"、“ANY表达式”、“ALL表达式”、“IN表达式”、“NULLIF表达式”、“IS DISTINCT FROM表达式”、“IS OF表达式”。"(+)"不能出现在其他类型表达式中,并且这些表达式中不允许出现通过“AND”和“OR”连接的表达式。
    10. "(+)"只能转化为左外连接或者右外连接,不能转化为全连接,即不能在一个表达式的两个表上同时指定"(+)"。
    须知:
    • 对于WHERE子句的LIKE操作符,当LIKE中要查询特殊字符“%”、“_”、“\”的时候需要使用反斜杠“\”来进行转义。
    • WHERE子句后面添加IN子句且当IN后面不添加括号时,支持IN后面只添加一个元素,且约束仅支持在ORA兼容模式下使用。该元素有如下限制:
      • 常量:如字符串、整数、浮点数等。
      • 列名。
      • CASE WHEN子句。
      • 函数。
  • START WITH子句

    START WITH子句通常与CONNECT BY子句同时出现,数据进行层次递归遍历查询,START WITH代表递归的初始条件。若省略该子句,单独使用CONNECT BY子句,则表示以表中的所有行作为初始集合。该功能请参见CONNECT BY子句子句。

  • CONNECT BY子句

    CONNECT BY代表递归连接条件,和START WITH子句一起使用,实现数据遍历递归的功能。如:

    gaussdb=#  CREATE TABLE test(name varchar, id int, fatherid int);
    gaussdb=#  INSERT INTO test VALUES('A', 1, 0), ('B', 2, 1),('C',3,1),('D',4,1),('E',5,2);
    gaussdb=#  SELECT * FROM TEST START WITH id = 1 CONNECT BY prior id = fatherid ORDER SIBLINGS BY id DESC;
     name | id | fatherid 
    ------+----+----------
     A    |  1 |        0
     D    |  4 |        1
     C    |  3 |        1
     B    |  2 |        1
     E    |  5 |        2
    (5 rows)

    CONNECT BY条件中可以对列指定PRIOR关键字代表以这列为递归键进行递归。若在递归连接条件前加NOCYCLE,则表示遇到循环记录时停止递归。

    须知:

    含START WITH .. CONNECT BY子句的SELECT语句不支持使用FOR SHARE/UPDATE锁。

    START WITH语句的执行流程是:

    1. 由START WITH区域的条件选择初始的数据集。上述例子里,先把 ('A', 1, 0) 选择出来了。然后把初始的数据集设为工作集。
    2. 只要工作集不为空,会用工作集的数据作为输入,查询下一轮的数据,过滤条件由CONNECT BY区域指定。其中,PRIOR关键字表示当前记录,如上文例子中prior id = fatherid表示当前记录的id是下一条记录的fatherid。
    3. 2中筛选出来的数据集,设为工作集,重复操作2

    同时,数据库为每一条选出来的数据添加下述的伪列,方便用户了解数据在递归或者树状结构中的位置。

    • LEVEL:节点的层级,根节点层级为1。
    • CONNECT_BY_ISLEAF:是否为叶子节点。
      须知:

      connect_by_isleaf:当某个节点不存在任何子节点时,其即为叶子节点,connect_by_isleaf会被置为1;否则会被置为0。

      此处举例说明,假设存在表T1,其中数据如图1所示:
      图1 数据结构

      执行语句:

      SELECT * FROM T1 CONNECT BY PRIOR B=A AND LEVEL<=3; 
      其结果的树型结构如图2所示,其中蓝色的节点为叶子节点。
      图2 执行逻辑结构图

    除了伪列之外,还提供下述的查询函数(具体请参见层次递归查询函数)。

    • sys_connect_by_path(col, separator):返回从根节点到当前行的连接路径。参数col为路径中显示的列的名称,separator为连接符。
    • connect_by_root(col):显示该节点最顶级的节点,col为输出列的名称。

    如果数据集中存在循环,数据库会提供循环检测。默认行为检查到循环会直接报错,不返回任何数据。同时,提供NOCYCLE关键字,查询可以正常执行,只是碰到第一条重复的数据时,会直接退出,而不是报错。

    此外,在层次查询过程中,严格按照深度优先搜索的顺序进行。如果在START WITH或CONNECT中使用rownum作为过滤条件,对于每条尝试被返回的记录,rownum会先加1,之后按照rownum相关条件判断;对于不满足的记录,会被丢弃且rownum会减1。

    须知:
    • PRIOR 关键字只能出现在 CONNECT BY 语句中,不能出现在 START WITH 语句中。
    • 除targetlist外,"prior(单列)"会被解析为"prior 单列",不感知用户自定义的名为prior的函数。
    • 只能对表中的列指定PRIOR,不支持对表达式、伪列及类型转换指定PRIOR关键字,如 PRIOR (a + 1) 不被允许。
    • CONNECT BY 语句中,PRIOR 修饰的列不可以和 level/rownum 等伪列在同一个条件里;但是可以在不同条件里。如 (PRIOR a = level) 不允许, (PRIOR a = b) and (level = 1) 允许。不同条件指的是 CONNECT BY 语句最上层的 and 连接起来的条件。如(PRIOR a = 1 or level = 1)算作一个条件,也不被允许。
    • START WITH/CONNECT BY语句中禁止将伪列用于子链接,即类似于 "rownum = (子查询)" 或 "rownum in (子查询)"。
    • CONNECT BY子句中不建议使用ROWNUM,如需使用请充分测试,避免结果和预期不一致。
    • 在with as定义的cte上调用START WITH/CONNECT BY时,如果cte有多个,需要保证每一个cte的定义不依赖于其他cte。
    • 如果数据中不存在环路,但是报错runs into cycle,需要考虑增大max_recursive_times。
    • connect_by_isleaf、connect_by_iscycle和level类型均为int。
    • connect_by_isleaf、connect_by_iscycle和level在层次查询下,一定会被解析为伪列,不会解析为投影列中别名名称和伪列相同的列。
    • 不建议在定义带有层次查询的视图时引用其他视图。
    • START WITH调优建议:
      • 根据 CONNECT BY中的条件,建立对应的索引,来提高START WITH语句的性能。
      • 根据 explain performance中的计划识别瓶颈点,如果发现Recursive Union的递归部分的算子(内层计划)为 Hash JOIN,但是 Hash 表是针对临时表 tmp_result构建或者计划中显示hash表发生物化(batch大于1),可能是 work_mem 过小导致无法对外层数据表建立Hash表。可以通过调大 work_mem 参数来提高性能。

        说明:GaussDB会对小数据量的表有优化,把表的结果缓存在 hash 表中来提高性能,此时不需要索引。但是如果数据量超过 work_mem 的限制,该优化会失效,此时可采用建立索引的方式尝试优化。

    • prior关键字只能出现在CONNECT BY语句中,不能出现在START WITH语句中。
    • 只能对表中的列指定PRIOR,不支持对表达式、类型转换指定PRIOR关键字,如 prior (a + 1) 不被允许。
    • CONNECT BY 语句中,prior 修饰的列不可以和 level/rownum 等伪列在同一个条件里;但是可以在不同条件里。如 (prior a = level) 不允许, (prior a = b) and (level = 1) 允许。不同条件指的是 CONNECT BY语句最上层的 and 连接起来的条件。如(prior a = 1 or level = 1)算作一个条件,也不被允许。
    • START WITH语句中不建议使用伪列,如需使用请充分测试,避免结果和预期不一致。
    • START WITH语句中使用空或NULL表示递归初始条件为空,返回空值结果。
    • CONNECT BY语句中使用空表示递归条件为空,返回所有符合 START WITH 子句条件的结果。
    • PRIOR修饰的列仅支持如下类型:INT8、INT1、INT2、OID、INT4、BOOL、CHAR、NAME、FLOAT4、FLOAT8、ABSTIME、RELTIME、DATE、CASH、TIME、TIMESTAMP、TIMESTAMPTZ、SMALLDATETIME、UUID、INTERVAL、TIMETZ、INT2VECTOR、CLOB、NVARCHAR2、VARCHAR、TEXT、VECTOR、BPCHAR、RAW、BYTEA、NUMERIC、XID、CID以及TID,且通过强制类型转换为上述类型的操作无法绕开白名单限制,如:PRIOR col::text(其中col不是上述白名单中的类型)。
    当前START WITH默认行为是宽度优先搜索。但可以通过和伪列配合,实现深度优先搜索。如:
    gaussdb=# SELECT sys_connect_by_path(name,'-') as path, *, LEVEL FROM test START WITH id = 1 CONNECT BY fatherid=prior id ORDER BY path;
      path  | name | id | fatherid | level 
    --------+------+----+----------+-------
     -A     | A    |  1 |        0 |     1
     -A-B   | B    |  2 |        1 |     2
     -A-B-E | E    |  5 |        2 |     3
     -A-C   | C    |  3 |        1 |     2
     -A-D   | D    |  4 |        1 |     2
    gaussdb=# DROP TABLE test;

    如果数据集中存在循环,数据库会提供循环检测。默认行为检查到循环会直接报错,不返回任何数据。同时,提供NOCYCLE关键字,查询可以正常执行,只是碰到第一条重复的数据时,会直接退出,而不是报错。

  • ORDER SIBLINGS BY子句

    START WITH语句输出时,不同层的数据会依次返回。但是在每一层内部,是没有任何顺序保证的,这是因为每一轮查询的过程中,数据库会自动选择最优的执行路径。上文的例子中,保证A会被先输出,但是B、C、D之间的顺序不固定。如果用户对最终输出顺序有需求,可以用ORDER SIBLINGS BY子句,用法和ORDER BY子句一样,用于在递归过程中每层内部的排序。

    须知:

    ORDER SIBLINGS BY后的表达式仅支持对普通列、列名偏移量、以及对列名的窗口函数调用的方式进行排序,不支持对列名调用START WITH相关系统函数和使用START WITH相关伪列等方式。

  • GROUP BY子句

    将查询结果按某一列或多列的值分组,值相等的为一组。

    • CUBE ( { expression | ( expression [, ...] ) } [, ...] )

      CUBE是自动对GROUP BY子句中列出的字段进行分组汇总,结果集将包含维度列中各值的所有可能组合,以及与这些维度值组合相匹配的基础行中的聚合值。它会为每个分组返回一行汇总信息, 用户可以使用CUBE来产生交叉表值。如在CUBE子句中给出三个表达式(n = 3),运算结果为2n = 23 = 8组。 以n个表达式的值分组的行称为常规行,其余的行称为超级聚集行。

    • GROUPING SETS ( grouping_element [, ...] )

      GROUPING SETS子句是GROUP BY子句的进一步扩展,它可以使用户指定多个GROUP BY选项,这样做可以通过裁剪用户不需要的数据组来提高效率。 当用户指定了所需的数据组时,数据库不需要执行完整CUBE或ROLLUP生成的聚合集合。

    须知:
    • 如果SELECT列表的表达式中引用了那些没有分组的字段,则会报错,除非使用了聚集函数,因为对于未分组的字段,可能返回多个数值。
    • 如果SELECT列表的表达式中引用了常量,则无需在GROUP BY子句中对该常量进行分组,否则会报错。
    • 当在GROUP BY子句中使用主键时,SELECT语句中的所有非聚合列都可以出现在结果集中,因为主键的唯一性确保了每个分组中的非聚合列值的确定性。
  • HAVING子句

    与GROUP BY子句配合用来选择特殊的组。HAVING子句将组的一些属性与一个常数值比较,只有满足HAVING子句中的逻辑表达式的组才会被提取出来。

  • WINDOW子句

    一般形式为WINDOW window_name AS ( window_definition ) [, ...],window_name是可以被随后的窗口定义所引用的名称,window_definition可以是以下的形式:

    [ existing_window_name ]
    [ PARTITION BY expression [, ...] ]
    [ ORDER BY expression [ ASC | DESC | USING operator ] [ NULLS { FIRST | LAST } ] [, ...] ]
    [ frame_clause ]

    frame_clause为窗函数定义一个窗口框架window frame,窗函数(并非所有)依赖于框架,window frame是当前查询行的一组相关行。frame_clause可以是以下的形式:

    [ RANGE | ROWS ] frame_start
    [ RANGE | ROWS ] BETWEEN frame_start AND frame_end

    frame_start和frame_end形式为:

    UNBOUNDED PRECEDING
    VALUE PRECEDING
    CURRENT ROW
    VALUE FOLLOWING
    UNBOUNDED FOLLOWING
    说明:

    针对使用到VALUE场景存在如下约束:

    • 被聚集函数/窗口窗口操作的表列仅支持INT1、INT2、INT4、INT8、FLOAT4、FLOAT8、NUMERIC、INTERVAL、TIME、TIMETZ、TIMESTAMP、TIMESTAMPTZ和DATE类型。
    • VALUE类型仅支持INT1、INT2、INT4、INT8、INT16、FLOAT4、FLOAT8、NUMERIC、INTERVAL和字符串(仅支持可以隐式转换为数字的字符串)类型。
    • VALUE的值一定为非负数。
    • VALUE当前只支持常量作为上下边界,不支持变量与表达式。
  • UNION子句

    UNION计算多个SELECT语句返回行集合的并集。

    UNION子句有如下约束条件:

    • 除非声明了ALL子句,否则缺省的UNION结果不包含重复的行。
    • 多个SELECT语句中列的数量必须相同,每列的数据类型以及顺序必须相同。
    • 同一个SELECT语句中的多个UNION操作符是从左向右计算的,除非用圆括弧进行了标识。
    • FOR UPDATE不能在UNION的结果或输入中声明。

    一般表达式:

    select_statement UNION [ALL] select_statement
    • select_statement可以是任何没有ORDER BY、LIMIT、FOR UPDATE子句的SELECT语句。
    • 如果用圆括弧包围,ORDER BY和LIMIT可以附着在子表达式里。
    须知:

    拼接UNION ALL子句时,推荐子句个数<100,超出时需保证实例内存足够,以避免内存不足。

  • INTERSECT子句

    INTERSECT计算多个SELECT语句返回行集合的交集,不含重复的记录。

    INTERSECT子句有以下约束条件:

    • 同一个SELECT语句中的多个INTERSECT操作符是从左向右计算的,除非用圆括弧进行了标识。
    • 当对多个SELECT语句的执行结果进行UNION和INTERSECT操作的时候,会优先处理INTERSECT。

    一般形式:

    select_statement INTERSECT select_statement

    select_statement可以是任何没有FOR UPDATE子句的SELECT语句。

  • EXCEPT子句

    EXCEPT子句有如下的通用形式:

    select_statement EXCEPT [ ALL ] select_statement

    select_statement是任何没有FOR UPDATE子句的SELECT表达式。

    EXCEPT操作符计算存在于左边SELECT语句的输出而不存在于右边SELECT语句输出的行。

    EXCEPT的结果不包含任何重复的行,除非声明了ALL选项。使用ALL时,一个在左边表中有m个重复而在右边表中有n个重复的行将在结果中出现max(m-n,0) 次。

    除非用圆括弧指明顺序,否则同一个SELECT语句中的多个EXCEPT操作符是从左向右计算的。EXCEPT和UNION的绑定级别相同。

    目前,不能给EXCEPT的结果或者任何EXCEPT的输入声明FOR UPDATE子句。

  • MINUS子句

    与EXCEPT子句具有相同的功能和用法。

  • ORDER BY子句

    对SELECT语句检索得到的数据进行升序或降序排序。对于ORDER BY表达式中包含多列的情况:

    • 首先根据最左边的列进行排序,如果这一列的值相同,则根据下一个表达式进行比较,以此类推。
    • 如果对于所有声明的表达式都相同,则按随机顺序返回。
    • 在与DISTINCT关键字一起使用的情况下,ORDER BY中排序的列必须包括在SELECT语句所检索的结果集的列中。
    • 在与GROUP BY子句一起使用的情况下,ORDER BY中排序的列必须包括在SELECT语句所检索的结果集的列中。

    对于不与GROUP BY子句一起使用,并且SELECT语句所检索的结果集的列中包含聚合函数的情况:

    • 如果检索的结果集的列中不包含集合返回函数,则忽略ORDER BY子句。
    • 如果检索的结果集的列中同时包含集合返回函数,则仅保留对集合返回函数列的排序,忽略其他排序。
    说明:

    如果要支持中文拼音排序,需要在初始化数据库时指定编码格式为UTF-8、GB18030、GB18030_2022、GBK或ZHS16GBK。命令如下:

    initdb –E UTF8 –D ../data –locale=zh_CN.UTF-8
    initdb -E GB18030 -D ../data -locale=zh_CN.GB18030
    initdb -E GB18030_2022 -D ../data -locale=zh_CN.GB18030
    initdb –E GBK –D ../data –locale=zh_CN.GBK
    initdb –E ZHS16GBK –D ../data –locale=zh_CN.GBK
  • LIMIT子句

    LIMIT子句由两个独立的子句组成:

    LIMIT { count | ALL } 限制返回行数,count为指定行数,LIMIT ALL的效果和省略LIMIT子句一样。

    OFFSET start count声明返回的最大行数,而start声明开始返回行之前忽略的行数。如果两个都指定了,会在开始计算count个返回行之前先跳过start行。

    LIMIT子句不支持ROWNUM作为count或者offset。

  • OFFSET子句

    SQL:2008开始提出一种不同的语法:

    OFFSET start { ROW | ROWS }

    start声明开始返回行之前忽略的行数。

  • FETCH { FIRST | NEXT } [ count ] { ROW | ROWS } ONLY

    如果不指定count,默认值为1,FETCH子句限定返回查询结果从第一行开始的总行数。

  • FOR UPDATE子句

    FOR UPDATE子句将对SELECT检索出来的行进行加锁。这样避免它们在当前事务结束前被其他事务修改或者删除,即其他企图UPDATE、 DELETE、 SELECT FOR UPDATE这些行的事务将被阻塞,直到当前事务结束。

    为了避免操作等待其他事务提交,可使用NOWAIT选项,如果被选择的行不能立即被锁住,执行SELECT FOR UPDATE NOWAIT将会立即报错,而不是等待;WAIT n选项,如果被选择的行不能立即被锁住,等待n秒(其中,n为int类型,取值范围:0 <= n <= 2147483),n秒内获取锁则正常执行,否则报错;SKIP LOCKED选项,对表加锁时跳过已经加锁的行,SKIP LOCKED只能跳过行锁,对不同事务中锁与锁不互相阻塞的场景,如SELECT FOR SHARE - SELECT FOR SHARE SKIP LOCKED, SKIP LOCKED不会跳过锁。

    FOR SHARE的行为类似,只是它在每个检索出来的行上要求一个共享锁,而不是一个排他锁。一个共享锁阻塞其它事务执行UPDATE、DELETE、SELECT,不阻塞SELECT FOR SHARE。

    如果在FOR UPDATE或FOR SHARE中明确指定了表名称,则只有这些指定的表被锁定,其他在SELECT中使用的表将不会被锁定。否则,将锁定该命令中所有使用的表。

    如果FOR UPDATE或FOR SHARE应用于一个视图或者子查询,它同样将锁定所有该视图或子查询中使用到的表。

    多个FOR UPDATE和FOR SHARE子句可以用于为不同的表指定不同的锁定模式。

    如果一个表中同时出现(或隐含同时出现)在FOR UPDATE和FOR SHARE子句中,则按照FOR UPDATE处理。类似的,如果影响一个表的任意子句中出现了NOWAIT,该表将按照NOWAIT处理。

    须知:
    • 对于FOR UPDATE/SHARE,执行计划不能下推的SQL,直接返回报错信息;对于执行计划可以下推的,下推到DN执行。
    • 对投影列或者WHERE条件中存在rownum的查询不支持FOR UPDATE/SHARE。
    • 对于子查询是stream计划的FOR UPDATE/SHARE语句,不支持加锁的同一行被并发更新。
    • 对于ORDER BY FOR UPDATE/SHARE语句,stream计划的sort算子和lock算子执行顺序与其他计划有所差别,stream计划是先执行lock再执行sort,其他计划是先执行sort再执行lock。原因是因为stream计划如果数据不在当前DN,需要重分布数据,回到数据的原始DN去加锁。由于重分布后数据会变得无序,所以最后还要加sort算子。如果先sort后lock,这样会导致原始有序的数据重新变得无序,这时sort就无意义了,可以消除此sort算子。最终计划的执行顺序就由原始的sort -> lock -> sort变为了lock -> sort。
    • 对于FOR UPDATE/SHARE语句并发场景,业界有使用加ORDER BY对数据进行排序的方式来避免死锁,这种做法对于分布式来说是不可行的,因为DN的加锁顺序不能通过ORDER BY保证。另外加ORDER BY会造成性能开销,所以不建议加ORDER BY去解决死锁问题。
    • DATABASE LINK功能不支持SKIP LOCKED语法。
    • 分布式场景下不支持对多表FOR UPDATE/SHAR。
  • NLS_SORT

    指定某字段按照特殊方式排序。目前仅支持中文拼音格式排序和不区分大小写排序。如果要支持此排序方式,在创建数据库时需要指定编码格式为“UTF8”、”GB18030”、”GB18030_2022”、“GBK”或”ZHS16GBK”;如果指定为其他编码,如SQL_ASCII,则可能报错或者排序无效。

    取值范围:

    • SCHINESE_PINYIN_M,按照中文拼音排序。
    • generic_m_ci,不区分大小写排序(可选,仅支持纯英文不区分大小写排序)。
  • PARTITION子句

    查询某个分区表中相应分区的数据。

文档反馈

文档反馈

意见反馈

0/500

标记内容

同时提交标记内容

提示

您即将访问非华为云网站,请注意账号财产安全