子查询

子查询或称为内部查询,嵌套查询,指的是在数据库查询的WHERE子句中嵌入查询语句,相当于临时表。一个SELECT语句的查询结果能够作为另一个语句的输入值。

子查询可以与SELECT,INSERT,UPDATE和DELETE语句一起使用。

以下是子查询必须遵守的几个规则:

  • 子查询必须用括号括起来。
  • 子查询在SELECT子句中只能有一个列,除非在主查询中有多列,与子查询的所选列进行比较。
  • ORDER BY不能用在子查询中,虽然主查询可以使用ORDER BY。可以在子查询中使用GROUP BY,功能与ORDER BY相同。
  • 子查询返回多于一行,只能与多值运算符一起使用,如IN运算符。
  • BETWEEN运算符不能与子查询一起使用,但是,BETWEEN可在子查询内部使用。

SELECT语句中的子查询使用

SELECT语句在子查询返回的数据中进行查询。基本语法如下:

1. SELECT column_name [, column_name ]
2. FROM   table1 [, table2 ]
3. WHERE  column_name OPERATOR
4. (SELECT column_name [, column_name ]
5. FROM table1 [, table2 ]
6. [WHERE]);

示例:

创建表customer_t1,数据内容如下。

1. openGauss=# SELECT * FROM customer_t1;
2. c_customer_sk | c_customer_id | c_first_name | c_last_name | amount
3. ---------------+---------------+--------------+-------------+--------
4. 3869 | hello         | Grace        |             |   1000
5. 3869 |               | Grace        |             |
6. 3869 | hello         |              |             |
7. 6985 | maps          | Joes         |             |   2200
8. 9976 | world         | James        |             |   5000
9. 4421 | Admin         | Local        |             |   3000
10. (6 rows)

在SELECT中使用子查询,语句如下。

1. openGauss=# SELECT * FROM customer_t1 WHERE c_customer_sk IN (SELECT c_customer_sk FROM customer_t1 WHERE amount > 2500) ;
2. c_customer_sk | c_customer_id | c_first_name | c_last_name | amount
3. ---------------+---------------+--------------+-------------+--------
4. 9976 | world         | James        |             |   5000
5. 4421 | Admin         | Local        |             |   3000
6. (2 rows)

INSERT语句中的子查询使用

子查询也可以与INSERT语句一起使用。INSERT语句使用子查询返回的数据插入到另一个表中。基本语法如下:

1. INSERT INTO table_name [ (column1 [, column2 ]) ]
2. SELECT [ *|column1 [, column2 ] ]
3. FROM table1 [, table2 ]
4. [ WHERE VALUE OPERATOR ]

示例:

创建表customer_bak,表结构与customer_t1一致。

1. openGauss=# CREATE TABLE customer_bak
2. (
3. c_customer_sk             integer,
4. c_customer_id             char(5),
5. c_first_name              char(6),
6. c_last_name               char(8),
7. Amount                    integer
8. );
9. CREATE TABLE

将表customer_t1中的数据插入customer_bak。

1. openGauss=# INSERT INTO customer_bak SELECT * FROM customer_t1  WHERE c_customer_sk  IN (SELECT c_customer_sk  FROM customer_t1) ;
2. INSERT 0 6

插入数据后的customer_bak的表如下:

1. openGauss=# SELECT * FROM customer_bak;
2. c_customer_sk | c_customer_id | c_first_name | c_last_name | amount
3. ---------------+---------------+--------------+-------------+--------
4. 3869 | hello         | Grace        |             |   1000
5. 3869 |               | Grace        |             |
6. 3869 | hello         |              |             |
7. 6985 | maps          | Joes         |             |   2200
8. 9976 | world         | James        |             |   5000
9. 4421 | Admin         | Local        |             |   3000
10. (6 rows)

UPDATE语句中的子查询使用

通过UPDATE语句使用子查询时,表中多个列被更新。基本语法如下:

1. UPDATE table
2. SET column_name = new_value
3. [ WHERE OPERATOR [ VALUE ]
4. (SELECT COLUMN_NAME
5. FROM TABLE_NAME
6. [ WHERE ])

示例:

把表customer_t1中所有c_customer_sk大于4000的客户的amount更新为原来的0.50倍:

1. openGauss=# UPDATE customer_t1 SET amount = amount * 0.50 WHERE c_customer_sk IN (SELECT c_customer_sk FROM customer_bak WHERE c_customer_sk > 5000 );
2. UPDATE 2

更新影响2行,更新后表customer_t1数据如下:

1. openGauss=# SELECT *  FROM  customer_t1;
2. c_customer_sk | c_customer_id | c_first_name | c_last_name | amount
3. ---------------+---------------+--------------+-------------+--------
4. 3869 | hello         | Grace        |             |   1000
5. 3869 |               | Grace        |             |
6. 3869 | hello         |              |             |
7. 4421 | Admin         | Local        |             |   3000
8. 6985 | maps          | Joes         |             |   1100
9. 9976 | world         | James        |             |   2500
10. (6 rows)

DELETE语句中的子查询使用

基本语法如下:

1. DELETE FROM TABLE_NAME
2. [ WHERE OPERATOR [ VALUE ]
3. (SELECT COLUMN_NAME
4. FROM TABLE_NAME
5. [ WHERE ])

示例:

删除表customer_t1中所有c_customer_sk大于4000的客户:

1. openGauss=# DELETE FROM customer_t1 WHERE c_customer_sk IN (SELECT c_customer_sk FROM customer_bak WHERE  c_customer_sk > 5000 );
2. DELETE 2

删除影响2行,删除后的表customer_t1数据如下:

1. openGauss=# SELECT *  FROM  customer_t1;
2. c_customer_sk | c_customer_id | c_first_name | c_last_name | amount
3. ---------------+---------------+--------------+-------------+--------
4. 3869 | hello         | Grace        |             |   1000
5. 3869 |               | Grace        |             |
6. 3869 | hello         |              |             |
7. 4421 | Admin         | Local        |             |   3000
8. (4 rows)