SELECT

功能描述

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

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

注意事项

  • 对比原openGauss的SELECT语法,新增了WHERE子句下的sounds like语法。

  • 新增join不带on/using,效果与cross join一致。

  • 新增PARTITION子句可指定多个分区。

  • 新增UNION子句列如果没有相似的数据类型,会采取转换为text类型的方式进行处理。

  • 新增FROM DUAL 语法,含义等同于不写FROM子句,是为了满足那些要求所有SELECT语句都应该包含FROM的情况。

语法格式

  • 查询数据
[ 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 | NO KEY UPDATE | SHARE | KEY SHARE } [ OF table_name [, ...] ] [ NOWAIT ]} [...] ];
  • 其中指定查询源from_item为:

    {[ 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 [, ...] )
    |from_item [ NATURAL ] join_type from_item [ ON join_condition | USING ( join_column [, ...] ) ]}
    
  • 其中不写FROM 子句的情况等价于:

    FROM DUAL
    
  • 其中group子句为:

    ( )
    | expression
    | ( expression [, ...] )
    | rollup_clause
    | CUBE ( { expression | ( expression [, ...] ) } [, ...] )
    | GROUPING SETS ( grouping_element [, ...] )
    
  • 其中指定分区partition_clause为:

    PARTITION { ( partition_name [, ...] ) | 
            FOR (  partition_value [, ...] ) }
    

    说明: 指定分区只适合分区表。

    rollup_clause子句为:

    ROLLUP ( { expression | ( expression [, ...] ) } [, ...] )
    | { expression | ( expression [, ...] ) } WITH ROLLUP
    
  • JOIN语法

[JOIN | INNER JOIN] {ON join_condition | USING ( join_column [, ...] ) }

参数说明

  • WHERE子句

    sounds like是condition的一种语法,用法如:column_name sounds like '字符'; 相当于soundex(column_name) = soundex('字符')的对比结果,是一个boolean的值。用于通过soundex处理来查询满足条件的数据。

    where 子句可以包含兼容MySQL全文索引的查询语法。match(column_name [, …]) against ('匹配字符')也是condition的一种语法。

    where match(column_name [, ...]) against ('匹配字符');
    

    column_name可以是多列,列名之间用逗号分隔。 against()的匹配字符只能是字符内容(即全文索引支持字段类型只能是这三种char, varchar, text),不包含int, bool, 特殊字符(!,#,空格等)与正规功能。 注意: mysql的全文索引查询语法match(column_name)允许无序,但该功能底层用的是opengauss的to_tsvector(),他的要求是字段顺序必须有序(与表的字段顺序一致)。

    用于安装了dolphin插件,处于MySQL兼容性场景下的全文索引查询。其语法结构相当于

    to_tsvector('ngram', col_name [|| col_name]) @@ to_tsquery('字符串')
    
  • UNION子句 UNION计算多个SELECT语句返回行集合的并集。UNION内部的SELECT语句必须拥有相同数量的列,列如果没有相似的数据类型或者为UNKNOWN类型,会采取转换为text类型的方式进行处理。

    UNION子句有如下约束条件:

    • 除非声明了ALL子句,否则缺省的UNION结果不包含重复的行。
    • 同一个SELECT语句中的多个UNION操作符是从左向右计算的,除非用圆括弧进行了标识。
    • FOR UPDATE,FOR NO KEY UPDATE,FOR SHARE和FOR KEY SHARE不能在UNION的结果或输入中声明。

    一般表达式:

    select_statement UNION [ALL] select_statement

    • select_statement可以是任何没有ORDER BY、LIMIT、FOR UPDATE,FOR NO KEY UPDATE,FOR SHARE或FOR KEY SHARE子句的SELECT语句。
    • 如果用圆括弧包围,ORDER BY和LIMIT可以附着在子表达式里。

说明:

涉及的其它参数说明可见SELECT

示例

  • SOUNDS LIKE子句示例:同音字段查询
openGauss=# CREATE TABLE TEST(id int, name varchar);
openGauss=# INSERT INTO TEST VALUES(1, 'too');
openGauss=# SELECT * FROM TEST WHERE name SOUNDS LIKE 'two';
 id | name
----+------
  1 | too
(1 row)
  • SELECT GROUP BY子句中使用ROLLUP
openGauss=# CREATE TABLESPACE t_tbspace ADD DATAFILE 'my_tablespace' ENGINE = test_engine;
CREATE TABLESPACE
openGauss=# CREATE TABLE t_with_rollup(id int, name varchar(20), area varchar(50), count int);
CREATE TABLE
openGauss=# INSERT INTO t_with_rollup values(1, 'a', 'A', 10);
INSERT 0 1
openGauss=# INSERT INTO t_with_rollup values(2, 'b', 'B', 15);
INSERT 0 1
openGauss=# INSERT INTO t_with_rollup values(2, 'b', 'B', 20);
INSERT 0 1
openGauss=# INSERT INTO t_with_rollup values(3, 'c', 'C', 50);
INSERT 0 1
openGauss=# INSERT INTO t_with_rollup values(3, 'c', 'C', 15);
INSERT 0 1
openGauss=# SELECT name, sum(count) FROM t_with_rollup GROUP BY ROLLUP(name);
 name | sum
------+-----
 a    |  10
 b    |  35
 c    |  65
      | 110
(4 rows)

openGauss=# SELECT name, sum(count) FROM t_with_rollup GROUP BY (name) WITH ROLLUP;
 name | sum
------+-----
 a    |  10
 b    |  35
 c    |  65
      | 110
(4 rows)
openGauss=# create table join_1(col1 int4, col2 int8);

openGauss=# create table join_2(col1 int4, col2 int8);

openGauss=# insert into join_1 values(1, 2), (3, 3);

openGauss=# insert into join_2 values(1, 1), (2, 3), (4, 4);

openGauss=# select join_1 join join_2;

 col1 | col2 | col1 | col2
------+------+------+------
    1 |    2 |    1 |    1
    1 |    2 |    2 |    3
    1 |    2 |    4 |    4
    3 |    3 |    1 |    1
    3 |    3 |    2 |    3
    3 |    3 |    4 |    4

openGauss=# select join_1 inner join join_2;

 col1 | col2 | col1 | col2
------+------+------+------
    1 |    2 |    1 |    1
    1 |    2 |    2 |    3
    1 |    2 |    4 |    4
    3 |    3 |    1 |    1
    3 |    3 |    2 |    3
    3 |    3 |    4 |    4
  • SELECT 语句中使用FROM DUAL 示例
openGauss=# select 1 as col;
 col
-----
   1
(1 row)
openGauss=# select 1 as col FROM DUAL;
 col
-----
   1
(1 row)
  • SELECT FROM PARTITION子句指定多个分区
openGauss=# create table multi_partition_select_test(C_INT INTEGER) partition by range(C_INT)
openGauss-# (
openGauss(#     partition test_part1 values less than (400),
openGauss(#     partition test_part2 values less than (700),
openGauss(#     partition test_part3 values less than (1000)
openGauss(# );
CREATE TABLE
openGauss=# insert into multi_partition_select_test values(111);
INSERT 0 1
openGauss=# insert into multi_partition_select_test values(555);
INSERT 0 1
openGauss=# insert into multi_partition_select_test values(888);
INSERT 0 1

openGauss=# select a.* from multi_partition_select_test partition (test_part1, test_part2) a;
 c_int
-------
   111
   555
(2 rows)
  • UNION子句非相似数据类型按 TEXT 类型进行转换示例:
-- 首先创建兼容模式为B的数据库
CREATE DATABASE mydb WITH DBCOMPATIBILITY 'B';
\c mydb

-- 创建两个表并插入测试数据
CREATE TABLE tbl_date(col DATE);
INSERT INTO tbl_date VALUES('2000-02-16');
CREATE TABLE tbl_json(col JSON);
INSERT INTO tbl_json VALUES('{"id":1,"dbname":"openGauss","language":"C++"}');

-- UNION 查询,将会使用TEXT类型进行转换
SELECT * FROM tbl_date UNION SELECT * FROM tbl_json;
  • 兼容MySQL兼容性全文索引语法查询,前提是兼容模式为B的数据库。
openGauss=# CREATE SCHEMA fulltext_test;
CREATE SCHEMA
openGauss=# set current_schema to 'fulltext_test';
SET
openGauss=# CREATE TABLE test (
openGauss(# id int unsigned auto_increment not null primary key,
openGauss(# title varchar,
openGauss(# boby text,
openGauss(# name name,
openGauss(# FULLTEXT (title, boby) WITH PARSER ngram
openGauss(# );
NOTICE:  CREATE TABLE will create implicit sequence "test_id_seq" for serial column "test.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "test_pkey" for table "test"
CREATE TABLE
openGauss=# \d test
              Table "fulltext_test.test"
 Column |       Type        |        Modifiers
--------+-------------------+-------------------------
 id     | uint4             | not null AUTO_INCREMENT
 title  | character varying |
 boby   | text              |
 name   | name              |
Indexes:
    "test_pkey" PRIMARY KEY, btree (id) TABLESPACE pg_default
    "test_to_tsvector_to_tsvector1_idx" gin (to_tsvector('ngram'::regconfig, title::text), to_tsvector('ngram'::regconfig, boby)) TABLESPACE pg_default

openGauss=# \d test_to_tsvector_to_tsvector1_idx
      Index "fulltext_test.test_to_tsvector_to_tsvector1_idx"
    Column    | Type |                  Definition
--------------+------+----------------------------------------------
 to_tsvector  | text | to_tsvector('ngram'::regconfig, title::text)
 to_tsvector1 | text | to_tsvector('ngram'::regconfig, boby)
gin, for table "fulltext_test.test"

openGauss=# DROP INDEX test_to_tsvector_to_tsvector1_idx;
DROP INDEX
openGauss=# ALTER TABLE test ADD FULLTEXT INDEX test_index_1 (title, boby) WITH PARSER ngram;
ALTER TABLE
openGauss=# DROP INDEX test_index_1;
DROP INDEX
openGauss=# CREATE FULLTEXT INDEX test_index_1 ON test (title, boby) WITH PARSER ngram;
CREATE INDEX
openGauss=# \d test_index_1
                 Index "fulltext_test.test_index_1"
    Column    | Type |                  Definition
--------------+------+----------------------------------------------
 to_tsvector  | text | to_tsvector('ngram'::regconfig, title::text)
 to_tsvector1 | text | to_tsvector('ngram'::regconfig, boby)
gin, for table "fulltext_test.test"

openGauss=# INSERT INTO test(title, boby, name) VALUES('test', '&67575@gauss', 'opengauss');
INSERT 0 1
openGauss=# INSERT INTO test(title, boby, name) VALUES('test1', 'gauss', 'opengauss');
INSERT 0 1
openGauss=# INSERT INTO test(title, boby, name) VALUES('test2', 'gauss2', 'opengauss');
INSERT 0 1
openGauss=# INSERT INTO test(title, boby, name) VALUES('test3', 'test', 'opengauss');
INSERT 0 1
openGauss=# INSERT INTO test(title, boby, name) VALUES('gauss_123_@', 'test', 'opengauss');
INSERT 0 1
openGauss=# INSERT INTO test(title, boby, name) VALUES('', '', 'opengauss');
INSERT 0 1
openGauss=# INSERT INTO test(title, boby, name) VALUES(' ', ' ', ' ');
INSERT 0 1
openGauss=# SELECT * FROM TEST;
 id |    title    |     boby     |   name
----+-------------+--------------+-----------
 1  | test        | &67575@gauss | opengauss
 2  | test1       | gauss        | opengauss
 3  | test2       | gauss2       | opengauss
 4  | test3       | test         | opengauss
 5  | gauss_123_@ | test         | opengauss
 6  |             |              | opengauss
 7  |             |              |
(7 rows)

openGauss=# SELECT * FROM TEST WHERE MATCH (title, boby) AGAINST ('test');
 id |    title    |     boby     |   name
----+-------------+--------------+-----------
 1  | test        | &67575@gauss | opengauss
 2  | test1       | gauss        | opengauss
 3  | test2       | gauss2       | opengauss
 4  | test3       | test         | opengauss
 5  | gauss_123_@ | test         | opengauss
(5 rows)

openGauss=# SELECT * FROM TEST WHERE MATCH (title, boby) AGAINST ('gauss');
 id |    title    |     boby     |   name
----+-------------+--------------+-----------
 1  | test        | &67575@gauss | opengauss
 2  | test1       | gauss        | opengauss
 3  | test2       | gauss2       | opengauss
 5  | gauss_123_@ | test         | opengauss
(4 rows)

openGauss=# DROP INDEX test_index_1;
DROP INDEX
openGauss=# CREATE FULLTEXT INDEX test_index_1 ON test (boby) WITH PARSER ngram;
CREATE INDEX
openGauss=# \d test_index_1
             Index "fulltext_test.test_index_1"
   Column    | Type |              Definition
-------------+------+---------------------------------------
 to_tsvector | text | to_tsvector('ngram'::regconfig, boby)
gin, for table "fulltext_test.test"

openGauss=# SELECT * FROM test WHERE MATCH (boby) AGAINST ('test');
 id |    title    | boby |   name
----+-------------+------+-----------
 4  | test3       | test | opengauss
 5  | gauss_123_@ | test | opengauss
(2 rows)

openGauss=# SELECT * FROM test WHERE MATCH (boby) AGAINST ('gauss');
 id | title |     boby     |   name
----+-------+--------------+-----------
 1  | test  | &67575@gauss | opengauss
 2  | test1 | gauss        | opengauss
 3  | test2 | gauss2       | opengauss
(3 rows)

openGauss=# DROP INDEX test_index_1;
DROP INDEX
openGauss=# CREATE FULLTEXT INDEX test_index_1 ON test (title, boby, name) WITH PARSER ngram;
CREATE INDEX
openGauss=# \d test_index_1
                 Index "fulltext_test.test_index_1"
    Column    | Type |                  Definition
--------------+------+----------------------------------------------
 to_tsvector  | text | to_tsvector('ngram'::regconfig, title::text)
 to_tsvector1 | text | to_tsvector('ngram'::regconfig, boby)
 to_tsvector2 | text | to_tsvector('ngram'::regconfig, name::text)
gin, for table "fulltext_test.test"

openGauss=# SELECT * FROM test WHERE MATCH (title, boby, name) AGAINST ('test');
 id |    title    |     boby     |   name
----+-------------+--------------+-----------
 1  | test        | &67575@gauss | opengauss
 2  | test1       | gauss        | opengauss
 3  | test2       | gauss2       | opengauss
 4  | test3       | test         | opengauss
 5  | gauss_123_@ | test         | opengauss
(5 rows)

openGauss=# SELECT * FROM test WHERE MATCH (title, boby, name) AGAINST ('gauss');
 id |    title    |     boby     |   name
----+-------------+--------------+-----------
 1  | test        | &67575@gauss | opengauss
 2  | test1       | gauss        | opengauss
 3  | test2       | gauss2       | opengauss
 4  | test3       | test         | opengauss
 5  | gauss_123_@ | test         | opengauss
 6  |             |              | opengauss
(6 rows)

openGauss=# SELECT * FROM test WHERE MATCH (title, boby, name) AGAINST ('opengauss');
 id |    title    |     boby     |   name
----+-------------+--------------+-----------
 1  | test        | &67575@gauss | opengauss
 2  | test1       | gauss        | opengauss
 3  | test2       | gauss2       | opengauss
 4  | test3       | test         | opengauss
 5  | gauss_123_@ | test         | opengauss
 6  |             |              | opengauss
(6 rows)

openGauss=# drop table if exists articles;
NOTICE:  table "articles" does not exist, skipping
DROP TABLE
openGauss=# CREATE TABLE articles (
openGauss(# ID int,
openGauss(# title VARCHAR(100),
openGauss(# FULLTEXT INDEX ngram_idx(title)WITH PARSER ngram
openGauss(# );
CREATE TABLE
openGauss=# \d articles
       Table "fulltext_test.articles"
 Column |          Type          | Modifiers
--------+------------------------+-----------
 ID     | integer                |
 title  | character varying(100) |
Indexes:
    "ngram_idx" gin (to_tsvector('ngram'::regconfig, title::text)) TABLESPACE pg_default

openGauss=# drop table if exists articles;
DROP TABLE
openGauss=# CREATE TABLE articles (
openGauss(# ID int,
openGauss(# title VARCHAR(100),
openGauss(# FULLTEXT INDEX (title)WITH PARSER ngram
openGauss(# );
CREATE TABLE
openGauss=# \d articles
       Table "fulltext_test.articles"
 Column |          Type          | Modifiers
--------+------------------------+-----------
 ID     | integer                |
 title  | character varying(100) |
Indexes:
    "articles_to_tsvector_idx" gin (to_tsvector('ngram'::regconfig, title::text)) TABLESPACE pg_default

openGauss=# drop table if exists articles;
DROP TABLE
openGauss=# CREATE TABLE articles (
openGauss(# ID int,
openGauss(# title VARCHAR(100),
openGauss(# FULLTEXT KEY keyngram_idx(title)WITH PARSER ngram
openGauss(# );
CREATE TABLE
openGauss=# \d articles
       Table "fulltext_test.articles"
 Column |          Type          | Modifiers
--------+------------------------+-----------
 ID     | integer                |
 title  | character varying(100) |
Indexes:
    "keyngram_idx" gin (to_tsvector('ngram'::regconfig, title::text)) TABLESPACE pg_default

openGauss=# drop table if exists articles;
DROP TABLE
openGauss=# CREATE TABLE articles (
openGauss(# ID int,
openGauss(# title VARCHAR(100),
openGauss(# FULLTEXT KEY (title)WITH PARSER ngram
openGauss(# );
CREATE TABLE
openGauss=# \d articles
       Table "fulltext_test.articles"
 Column |          Type          | Modifiers
--------+------------------------+-----------
 ID     | integer                |
 title  | character varying(100) |
Indexes:
    "articles_to_tsvector_idx" gin (to_tsvector('ngram'::regconfig, title::text)) TABLESPACE pg_default

openGauss=# create table table_ddl_0154(col1 int,col2 varchar(64), FULLTEXT idx_ddl_0154(col2));
CREATE TABLE
openGauss=# create table table_ddl_0085(
openGauss(# id int(11) not null,
openGauss(# username varchar(50) default null,
openGauss(# sex varchar(5) default null,
openGauss(# address varchar(100) default null,
openGauss(# score_num int(11));
CREATE TABLE
openGauss=# create fulltext index idx_ddl_0085_02 on table_ddl_0085(username);
CREATE INDEX
openGauss=# insert into table_ddl_0085 values (1,'test','m','xi''an changanqu', 10001), (2,'tst','w','xi''an beilingqu', 10002),
(3,'es','w','xi''an yangtaqu', 10003),(4,'s','m','beijingchaoyangqu', 10004);
INSERT 0 4
openGauss=# SELECT * FROM table_ddl_0085 WHERE MATCH (username) AGAINST ('te' IN NATURAL LANGUAGE MODE);
 id | username | sex |     address     | score_num
----+----------+-----+-----------------+-----------
  1 | test     | m   | xi'an changanqu |     10001
(1 row)

openGauss=# SELECT * FROM table_ddl_0085 WHERE MATCH (username) AGAINST ('ts' IN NATURAL LANGUAGE MODE WITH QUERY EXPANSION);
 id | username | sex |     address     | score_num
----+----------+-----+-----------------+-----------
  2 | tst      | w   | xi'an beilingqu |     10002
(1 row)

openGauss=# SELECT * FROM table_ddl_0085 WHERE MATCH (username) AGAINST ('test' IN BOOLEAN MODE);
 id | username | sex |     address     | score_num
----+----------+-----+-----------------+-----------
  1 | test     | m   | xi'an changanqu |     10001
(1 row)

openGauss=# SELECT * FROM table_ddl_0085 WHERE MATCH (username) AGAINST ('es' WITH QUERY EXPANSION);
 id | username | sex |     address     | score_num
----+----------+-----+-----------------+-----------
  1 | test     | m   | xi'an changanqu |     10001
  3 | es       | w   | xi'an yangtaqu  |     10003
(2 rows)

openGauss=# SELECT * FROM table_ddl_0085 WHERE MATCH (username) AGAINST ('s');
 id | username | sex |      address      | score_num
----+----------+-----+-------------------+-----------
  4 | s        | m   | beijingchaoyangqu |     10004
(1 row)

openGauss=# insert into table_ddl_0085 select * from table_ddl_0085 where match (username) against ('te' IN NATURAL LANGUAGE MODE);
INSERT 0 1
openGauss=# select * from table_ddl_0085;
 id | username | sex |      address      | score_num
----+----------+-----+-------------------+-----------
  1 | test     | m   | xi'an changanqu   |     10001
  2 | tst      | w   | xi'an beilingqu   |     10002
  3 | es       | w   | xi'an yangtaqu    |     10003
  4 | s        | m   | beijingchaoyangqu |     10004
  1 | test     | m   | xi'an changanqu   |     10001
(5 rows)

openGauss=# create fulltext index idx_ddl_0085_03 on table_ddl_0085(username) with parser ngram visible;
CREATE INDEX
openGauss=# create fulltext index idx_ddl_0085_04 on table_ddl_0085(username) visible with parser ngram;
CREATE INDEX
openGauss=# create fulltext index idx_ddl_0085_05 on table_ddl_0085(username) visible;
CREATE INDEX
openGauss=# create fulltext index idx_ddl_0085_06 on table_ddl_0085(username) with parser ngram comment 'TEST FULLTEXT INDEX COMMENT';
CREATE INDEX
openGauss=# create fulltext index idx_ddl_0085_07 on table_ddl_0085(username) comment 'TEST FULLTEXT INDEX COMMENT' with parser ngram;
CREATE INDEX
openGauss=# create fulltext index idx_ddl_0085_08 on table_ddl_0085(username) comment 'TEST FULLTEXT INDEX COMMENT';
CREATE INDEX
openGauss=# drop schema fulltext_test cascade;
NOTICE:  drop cascades to 4 other objects
DETAIL:  drop cascades to table test
drop cascades to table articles
drop cascades to table table_ddl_0154
drop cascades to table table_ddl_0085
DROP SCHEMA
openGauss=# reset current_schema;
RESET

相关链接

SELECT

意见反馈
编组 3备份
    openGauss 2024-04-23 00:47:53
    取消