
# DELETE
#### 功能描述
DELETE从指定的表里删除满足WHERE子句的行。如果WHERE子句不存在，将删除表中所有行，结果只保留表结构。
#### 注意事项
- 表的所有者、被授予了表DELETE权限的用户或被授予DELETE ANY TABLE权限的用户有权删除表中数据，系统管理员默认拥有此权限。同时也必须有USING子句引用的表以及condition上读取的表的SELECT权限。
- 对于行存复制表，仅支持两种场景下的DELETE操作：
  - 有主键约束的场景。
  
  - 执行计划能下推的场景。
   
- 对于子查询是stream计划的DELETE语句，不支持删除的同一行被并发更新。
 
#### 语法格式
```
[ WITH [ RECURSIVE ] with_query [, ...] ]
DELETE [/*+ plan_hint */] [FROM] [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    [ USING using_list ]
    [ WHERE condition | WHERE CURRENT OF cursor_name ] 
    [ ORDER BY {expression [ ASC | DESC | USING operator ]}]
    [ LIMIT { count } ]
    [ RETURNING { * | { output_expr [ [ AS ] output_name ] } [, ...] } ];
```
其中with_query的详细格式为：
```
with_query_name [ ( column_name [, ...] ) ] AS [ [ NOT ] MATERIALIZED ]
( {select | values | insert | update | delete} )
```
#### 参数说明
- **WITH \[ RECURSIVE \] with_query \[, ...\]**
  用于声明一个或多个可以在主查询中通过名称引用的子查询，相当于临时表。
  如果声明了RECURSIVE，那么允许SELECT子查询通过名称引用它自己。
  - with_query_name指定子查询生成的结果集名称，在查询中可使用该名称访问子查询的结果集。
  
  - column_name指定子查询结果集中显示的列名。
  
  - 每个子查询可以是SELECT，VALUES，INSERT，UPDATE或DELETE语句。
  
  - 用户可以使用MATERIALIZED / NOT MATERIALIZED对CTE进行修饰。
    - 如果声明为MATERIALIZED，WITH查询将被物化，生成一个子查询结果集的拷贝，在引用处直接查询该拷贝，因此WITH子查询无法和主干SELECT语句进行联合优化（如谓词下推、等价类传递等），对于此类场景可以使用NOT MATERIALIZED进行修饰，如果WITH查询语义上可以作为子查询内联执行，则可以进行上述优化。
    
    - 如果用户没有显示声明物化属性则遵守以下规则：如果CTE只在所属主干语句中被引用一次，且语义上支持内联执行，则会被改写为子查询内联执行，否则以CTE Scan的方式物化执行。
     
   
- **plan_hint子句**
  以/\*+ \*/的形式在DELETE关键字后，用于对DELETE对应的语句块生成的计划进行hint调优，详细用法请参见章节[使用Plan Hint进行调优](https://support.huaweicloud.com/distributed-devg-v3-gaussdb/gaussdb-12-0272.html#ZH-CN_TOPIC_0000002200189930)。每条语句中只有第一个/\*+ plan_hint \*/注释块会作为hint生效，里面可以写多条hint。
  
- **ONLY**
  如果指定ONLY则只有该表被删除；如果没有声明，则该表和它的所有子表将都被删除。
  
- **table_name**
  目标表的名称（可以有模式修饰）。
  取值范围：已存在的表名。
  ![](https://support.huaweicloud.com/distributed-devg-v3-gaussdb/public_sys-resources/note_3.0-zh-cn.png)
  支持使用DATABASE LINK方式对远端表进行操作，使用方式详情请见[DATABASE LINK](https://support.huaweicloud.com/distributed-devg-v3-gaussdb/gaussdb-12-1504.html#ZH-CN_TOPIC_0000002235390541)。
  
- **alias**
  目标表的别名。
  取值范围：字符串，符合[标识符命名规范](https://support.huaweicloud.com/distributed-devg-v3-gaussdb/gaussdb-12-0319.html#ZH-CN_TOPIC_0000002235270221__zh-cn_topic_0000002235098221_section14873217506)。
  
- **using_list**
  using子句。
  
- **condition**
  一个返回Boolean值的表达式，用于判断哪些行需要被删除。建议不要使用int等数值类型作为condition，因为int等数值类型可以隐式转换为bool值（非0值隐式转换为true，0转换为false），可能导致非预期的结果。
  
- **WHERE CURRENT OF cursor_name**
  当cursor指向表的某一行时，可以使用此语法删除cursor当前指向的行。使用限制及约束请参考[UPDATE](https://support.huaweicloud.com/distributed-devg-v3-gaussdb/gaussdb-12-0640.html#ZH-CN_TOPIC_0000002235270677)章节对此语法介绍。
  
- **ORDER BY子句**
  关键字详见[SELECT](https://support.huaweicloud.com/distributed-devg-v3-gaussdb/gaussdb-12-0628.html#ZH-CN_TOPIC_0000002235390501)章节介绍。
  
- **LIMIT**
  关键字详见[SELECT](https://support.huaweicloud.com/distributed-devg-v3-gaussdb/gaussdb-12-0628.html#ZH-CN_TOPIC_0000002235390501)章节介绍。
  
- **output_expr**
  DELETE命令删除行之后计算输出结果的表达式。该表达式可以使用表的任意字段，可以使用\*返回被删除行的所有字段。
  
- **output_name**
  一个字段的输出名称。
  取值范围：字符串，符合[标识符命名规范](https://support.huaweicloud.com/distributed-devg-v3-gaussdb/gaussdb-12-0319.html#ZH-CN_TOPIC_0000002235270221__zh-cn_topic_0000002235098221_section14873217506)。
  
 
#### 示例
```
--创建一个SCHEMA。
gaussdb=# CREATE SCHEMA tpcds;
--创建表tpcds.customer_address。
gaussdb=# CREATE TABLE tpcds.customer_address
(
ca_address_sk         INTEGER           NOT NULL,
ca_address_id         CHARACTER(16)     NOT NULL,
ca_street_number      INTEGER                    ,
ca_street_name        CHARACTER (20)
);
 
--向表中插入多条记录。
gaussdb=# INSERT INTO tpcds.customer_address VALUES (1, 'AAAAAAAABAAAAAAA', '18', 'Jackson'),(10000, 'AAAAAAAACAAAAAAA', '362', 'Washington 6th'),(15000, 'AAAAAAAADAAAAAAA', '585', 'Dogwood Washington');
--创建表tpcds.customer_address_bak。
gaussdb=# CREATE TABLE tpcds.customer_address_bak AS TABLE tpcds.customer_address;
--删除tpcds.customer_address_bak中ca_address_sk小于14888的职员。
gaussdb=# DELETE FROM tpcds.customer_address_bak WHERE ca_address_sk < 14888;
--删除tpcds.customer_address_bak中所有数据。
gaussdb=# DELETE FROM tpcds.customer_address_bak;
--删除tpcds.customer_address_bak表。
gaussdb=# DROP TABLE tpcds.customer_address_bak;
--删除tpcds.customer_address表。
gaussdb=# DROP TABLE tpcds.customer_address;
--删除SCHEMA。
gaussdb=# DROP SCHEMA tpcds CASCADE;
```
#### 优化建议
- delete 如果要删除表中的所有记录，建议使用truncate语法。
  
 
