The syntax of SELECT is complex. This topic describes the syntax of SIMPLE SELECT.
Purpose
You can use this statement to query data from a table or view.
Syntax
simple_select:
SELECT [ hint_options ] [ DISTINCT | UNIQUE | ALL] select_expr_list
FROM from_list
[WHERE condition]
[GROUP BY group_expression_list
[{ROLLUP | GROUPING SETS} group_expression_list]
[HAVING condition]
]
[ORDER BY order_expression_list]
[FOR UPDATE [OF column] [ {NOWAIT | WAIT integer | SKIP LOCKED } ] ]
select_expr_list:
table_name.*
| table_alias_name.*
| expr [[AS] column_alias_name]
from_list:
table_reference [, table_reference...]
table_reference:
simple_table
| joined_table
| pivot_clause
| unpivot_clause
| table_name@dblink_name
simple_table:
table_factor [partition_option] [[table_alias_name]
| (select_stmt) table_alias_name
| (table_reference_list)
joined_table:
table_reference [INNER] JOIN simple_table [join_condition]
| table_reference outer_join_type JOIN simple_table join_condition
partition_option:
PARTITION (partition_name_list)
partition_name_list:
partition_name [, partition_name...]
outer_join_type:
{LEFT | RIGHT | FULL} [OUTER]
join_condition:
ON expression
condition:
expression
group_expression_list:
group_expression [, group_expression...]
group_expression:
expression [ASC | DESC]
order_expression_list:
order_expression [, order_expression...]
order_expression:
expression [ASC | DESC]
pivot_clause:
PIVOT
(aggregate_function ( expr ) [[AS] alias ]
[, aggregate_function ( expr ) [[AS] alias ]... ]
pivot_for_clause
pivot_in_clause
)
pivot_for_clause:
FOR { column| ( column [, column... ]) }
pivot_in_clause
IN
( { { expr| ( expr [, expr...] ) } [ [ AS] alias]... }
[, { { expr| ( expr [, expr...] ) } [ [ AS] alias] ...} ]
)
unpivot_clause:
UNPIVOT [ {INCLUDE | EXCLUDE} NULLS ]
( { column | ( column [, column... ]) }
pivot_for_clause
unpivot_in_clause
)
unpivot_in_clause:
IN
( { column | ( column [, column... ]) }[ AS { literal | ( literal [, literal... ]) } ]
[, { column | ( column [, column... ] ) }[ AS {literal | ( literal [, literal... ]) } ]]
)
Parameters
| Parameter | Description |
|---|---|
| hint_options | The hint option, which is optional. |
| DISTINCT | UNIQUE | ALL | The returned data may contain duplicate rows.
|
| select_expr_list | The expressions or column names that you want to query from the database. Separate them with commas (,). You can use an asterisk (*) to indicate all columns.
|
| FROM table_references | The object from which data is selected. |
| PARTITION(partition_list) | The partition information of the table to be queried. For example: partition(p0,p1...) |
| table_alias_name | The alias of the object from which data is selected, in the format of original name+space+alias. |
| joined_table | The join method in a multi-table query.
|
| ON expression | The join condition in a multi-table join. |
| WHERE where_conditions | The filter condition, which is optional. Only the data that meets the condition is returned in the query results. where_conditions is an expression. |
| GROUP BY group_by_list | The grouping field, which is usually used together with aggregate functions. Note If no column following the SELECT clause uses any aggregate function, the columns following the SELECT clause must be specified after the GROUP BY clause. |
| ROLLUP group_expression_list | Rolls up the results of the groups created by the GROUP BY clause and generates the statistics. |
| GROUPING SETS group_expression_list | Specifies two or more data groups in a query, generates statistics, and aggregates and displays the statistics of the specified group. You can specify a single field or a list of fields in GROUPING SETS. |
| HAVING search_conditions | Filters the grouped data. The HAVING clause is similar to the WHERE clause, but the HAVING clause can reference an aggregate function such as SUM and AVG. |
| ORDER BY order_list | Sorts the query results by one or multiple columns in ascending (ASC) or descending (DESC) order. If you do not specify ASC or DESC, the default value ASC prevails.
|
| FOR UPDATE | Imposes an exclusive lock on all the rows in the query results to prevent other concurrent transactions from changing or reading the rows in some transaction isolation levels.
Note SKIP LOCKED is not supported in a multi-table join. |
| pivot_clause | Pivots a row to a column. |
| aggregate_function | The aggregate function. |
| expr | The expression whose calculation results are constant values. pivot_in_clause supports only constant expressions. |
| unpivot_clause | Pivots a column to a row. |
| dblink_name | The name of the database link (dblink) to be accessed. |
Examples
Create a table named tbl1.
obclient> CREATE TABLE tbl1 (id INT,name VARCHAR(10),num INT);
Query OK, 0 rows affected
obclient> INSERT INTO tbl1 VALUES (1, 'a',100),(2, 'b',200),(3, 'a',50);
Query OK, 3 rows affected
Records: 3 Duplicates: 0 Warnings: 0
obclient> SELECT * FROM tbl1;
+------+------+------+
| ID | NAME | NUM |
+------+------+------+
| 1 | a | 100 |
| 2 | b | 200 |
| 3 | a | 50 |
+------+------+------+
3 rows in set
Query the data in the
namefield from thetbl1table.obclient> SELECT name FROM tbl1; +------+ | NAME | +------+ | a | | b | | a | +------+ 3 rows in set
Query and deduplicate the data in the
namefield from thetbl1table.obclient> SELECT DISTINCT name FROM tbl1; +------+ | NAME | +------+ | a | | b | +------+ 2 rows in set
Query the
id,name, andnumvalues from thetbl1table, divide thenumvalues by 2, and name the output column asavg.obclient> SELECT id, name, num/2 AS avg FROM tbl1; +------+------+------+ | ID | NAME | AVG | +------+------+------+ | 1 | a | 50 | | 2 | b | 100 | | 3 | a | 25 | +------+------+------+ 3 rows in set
Query the values of the
id,name, andnumfields from thetbl1table based on the filter conditionname = 'a'.obclient> SELECT id, name, num FROM tbl1 WHERE name = 'a'; +------+------+------+ | ID | NAME | NUM | +------+------+------+ | 1 | a | 100 | | 3 | a | 50 | +------+------+------+ 2 rows in set
Query the
nameandnumvalues from thetbl1table, calculate the sum of thenumvalues byname, and return the rows with a sum of less than160.obclient> SELECT name,SUM(num) sum FROM tbl1 GROUP BY name HAVING SUM(num) < 160; +------+------+ | NAME | SUM | +------+------+ | a | 150 | +------+------+ 1 row in set
Query the values of the
id,name, andnumfields from thetbl1table, and return the query results bynumin ascending order.obclient> SELECT * FROM tbl1 ORDER BY num ASC; +------+------+------+ | ID | NAME | NUM | +------+------+------+ | 3 | a | 50 | | 1 | a | 100 | | 2 | b | 200 | +------+------+------+ 3 rows in set
Query all columns from the
tbl1table, and return the query results bynamein descending order and bynumin ascending order.obclient> SELECT * FROM tbl1 ORDER BY name DESC,num ASC; +------+------+------+ | ID | NAME | NUM | +------+------+------+ | 2 | b | 200 | | 3 | a | 50 | | 1 | a | 100 | +------+------+------+ 3 rows in set (0.00 sec)Query the row with a specified
idfrom thetbl1table, and use theFOR UPDATEclause to lock the row in the result set./*Query and lock the row where the ID is 1 in the tbl1 table of session 1.*/ obclient> SELECT * FROM tbl1 WHERE id=1 FOR UPDATE; +------+------+------+ | ID | NAME | NUM | +------+------+------+ | 1 | a | 100 | +------+------+------+ 1 row in set /*Query and lock the rows where the ID is 1 or 2 in the tbl1 table of session 2.*/ obclient> SELECT * FROM tbl1 WHERE id=1 or id=2 FOR UPDATE; ORA-30006: resource busy; acquire with WAIT timeout expired obclient> SELECT * FROM tbl1 WHERE id=1 or id=2 FOR UPDATE SKIP LOCKED; +------+------+------+ | ID | NAME | NUM | +------+------+------+ | 2 | b | 200 | +------+------+------+ 1 row in setQuery rows from the
tbl1table bynameandnumand calculate the number of rows in each result set.obclient> SELECT name, num, COUNT(*) from tbl1 GROUP BY GROUPING SETS(name, num); +------+------+----------+ | NAME | NUM | COUNT(*) | +------+------+----------+ | a | NULL | 2 | | b | NULL | 1 | | NULL | 100 | 1 | | NULL | 200 | 1 | | NULL | 50 | 1 | +------+------+----------+ 5 rows in set (0.01 sec)Pivot the rows in the
emp_phonetable to columns, and then pivot the columns to rows.obclient> CREATE TABLE emp(name VARCHAR2(50), num CHAR, phone VARCHAR2(50)); Query OK, 0 rows affected obclient> INSERT INTO emp VALUES('ZhangSan', '1', '1234-5678'),('ZhangSan', '2', '3219-6066'),('ZhangSan', '3', '5365-9583'); Query OK, 3 rows affected Records: 3 Duplicates: 0 Warnings: 0 obclient> SELECT * FROM emp; +----------+------+-----------+ | NAME | NUM | PHONE | +----------+------+-----------+ | ZhangSan | 1 | 1234-5678 | | ZhangSan | 2 | 3219-6066 | | ZhangSan | 3 | 5365-9583 | +----------+------+-----------+ 3 rows in set /*Pivot the rows in the emp table to columns.*/ obclient> SELECT * FROM emp PIVOT(MAX(phone) FOR num IN (1 AS home, 2 AS office, 3 AS mobile)); +----------+-----------+-----------+-----------+ | NAME | HOME | OFFICE | MOBILE | +----------+-----------+-----------+-----------+ | ZhangSan | 1234-5678 | 3219-6066 | 5365-9583 | +----------+-----------+-----------+-----------+ 1 row in set /*Pivot the columns in the emp table to rows.*/ obclient> CREATE VIEW v_emp AS SELECT * FROM emp PIVOT(MAX(phone) FOR num IN (1 AS home, 2 AS office, 3 AS mobile)); Query OK, 0 rows affected obclient> SELECT * FROM v_emp UNPIVOT(phone FOR num IN (home AS 1, office AS 2, mobile AS 3)); +----------+-----+-----------+ | NAME | NUM | PHONE | +----------+-----+-----------+ | ZhangSan | 1 | 1234-5678 | | ZhangSan | 2 | 3219-6066 | | ZhangSan | 3 | 5365-9583 | +----------+-----+-----------+ 3 rows in setQuery the data of a table in the remote database.
/*Access the remote OceanBase database to query data.*/ obclient> SELECT ID FROM tbl2@ob_dblink; +------+ | ID | +------+ | 1 | | 2 | | 3 | +------+ 3 rows in set obclient> SELECT * FROM tbl2@ob_dblink; +------+------+------+ | ID | NAME | NUM | +------+------+------+ | 1 | a | 100 | | 2 | b | 200 | | 3 | a | 50 | +------+------+------+ 3 rows in set (0.03 sec) /*Query the data in the local and remote databases concurrently.*/ obclient> SELECT t4.col1,t5.col2 FROM tbl1 t4, tbl2@ob_dblink t5 WHERE t1.col3=t2.col3;