Skip to content

查询语法

顶层查询语句selectstmt

语法格式

sql
selectstmt::=
    select_no_parens
|   select_with_parens
|   with_clauses select_no_parens

参数说明

  • select_no_parens:没有外部括号的简单选择语句。
  • select_with_parens:带有外部括号的选择语句,可以用于嵌套查询。
  • with_clauses select_no_parens:包含WITH子句的选择语句。

select_no_parens

语法格式

sql
select_no_parens ::= 
    simple_select
|   {simple_select | select_with_parens} sort_clause [NULLS FIRST | NULLS LAST] opt_for_update_clause opt_select_limit
|   {simple_select | select_with_parens} sort_clause opt_for_update_clause opt_select_limit
|   {simple_select | select_with_parens} for_update_clause opt_select_limit
|   {simple_select | select_with_parens} select_limit
|   {simple_select | select_with_parens} FOR SNAPSHOT OF ICONST AFTER ICONST START AT ICONST opt_select_limit

参数说明

  • simple_select:简单的选择语句。
  • sort_clause:对结果集进行排序。
  • opt_for_update_clausefor_update_clause:在查询时对结果集中的行进行锁定、只读。
  • opt_select_limitselect_limit:查询中用于限制返回行数。
  • FOR SNAPSHOT OF ICONST AFTER ICONST START AT ICONST opt_select_limit:基于时间点的快照选择语句。

简单查询simple_select

语法格式

sql
simple_select ::= 
    base_select
|   set_operation

base_select ::= 
    SELECT [HINT_TEXT] [TOP ICONST] [DISTINCT | ALL] target_list 
                opt_bulk opt_into_list opt_from_clause opt_where_clause 
                [opt_connect_by] opt_group_clause opt_having_clause

set_operation ::= 
    {simple_select | select_with_parens} UNION [ALL | DISTINCT] {simple_select | select_with_parens}
|   {simple_select | select_with_parens} INTERSECT [ALL | DISTINCT] {simple_select | select_with_parens}
|   {simple_select | select_with_parens} EXCEPT [ALL | DISTINCT] {simple_select | select_with_parens}
|   {simple_select | select_with_parens} MINUS [ALL | DISTINCT] {simple_select | select_with_parens}

参数说明

  • base_select:包含所有可选组件的基础SELECT语句。

    • SELECT:核心关键字,用于指定要检索的数据。
    • [HINT_TEXT]:可选部分,优化访问路径。
    • [TOP ICONST]:可选部分,用来限制返回结果集中的记录条数,同LIMIT ICONST一致,不可与LIMIT同时使用。
    • [DISTINCT | ALL]:可选部分,排除重复的记录。
    • target_list:必填部分,指定要选择的列或表达式。
    • opt_bulk:可选部分,用于批量操作。
    • opt_into_list:可选部分,用于将查询结果插入到变量或表中。
    • opt_from_clause:必填部分,指定查询的数据来源。
    • opt_where_clause:可选部分,用于指定过滤条件。
    • [opt_connect_by]:可选部分,用于层次查询。
    • opt_group_clause:可选部分,用于对查询结果进行分组。
    • opt_having_clause:可选部分,用于对分组后的结果进行过滤。
  • set_operation:多个SELECT语句之间的集合操作,如并集(UNION)、交集(INTERSECT)、差集(EXCEPT或MINUS)。

排序sort_clause

语法格式

sql
sort_clause::=
    ORDER BY sortby[,sortby]...

sortby::=
    b_expr [USING ROp | ASC | DESC] [NULLS FIRST | NULLS LAST]
    
ROp::=
    <
|   >
|   =
|   <=
|   >=
|   <>

参数说明

  • sort_clause:包含一个或多个sortby项的ORDER BY子句,可分为降序和升序,若无排序子句则默认为升序。
  • sortby:表达式及其排序方向(ASC或DESC),以及NULL值的处理方式(NULLS FIRST或NULLS LAST)。
  • ROp:比较运算符。

锁定opt_for_update_clause

语法格式

sql
opt_for_update_clause ::= 
    /* EMPTY */
|   for_update_clause

for_update_clause ::= 
    FOR UPDATE OF name_space [, name_space]...
|   FOR READ ONLY
|   FOR UPDATE

参数说明

  • opt_for_update_clause:可选FOR UPDATE子句,允许为空。
  • for_update_clause:明确指定要锁定的对象,或只读模式。

结果限制opt_select_limit

语法格式

sql
opt_select_limit ::= 
    /* EMPTY */
|   select_limit

select_limit ::= 
    LIMIT {ICONST | Param | :ICONST} ',' {ICONST | ALL | Param | :ICONST}
|   LIMIT {ICONST | ALL | Param | :ICONST} OFFSET {ICONST | Param | :ICONST}
|   LIMIT {ICONST | ALL | Param | :ICONST}

参数说明

  • opt_select_limit:可选的结果限制子句,允许为空。
  • select_limit:包含LIMIT和OFFSET的具体格式,数据分页限制子句,LIMIT限制数据条数,OFFSET限制数据开始位置。

目标列表target_list

语法格式

sql
target_list ::= target_el [, target_el]...

target_el ::= 
    b_expr AS ColLabel
|   b_expr ColId
|   DEFAULT
|   b_expr
|   ident . *
|   *
|   rop_bool_expr AS ColLabel
|   rop_bool_expr ColId
|   bool_expr1
|   '(' rop_bool_expr ')'

rop_bool_expr::=
    b_expr ROp b_expr
|   bool_expr1 ROp b_expr
|   b_expr ROp bool_expr1
|   bool_expr1 ROp bool_expr1
  
bool_expr1::=
    '(' bool_expr AND bool_expr ')'
|   '(' bool_expr OR bool_expr ')'
|   '(' NOT bool_expr ')'
|   '(' bool_expr1 ')'

参数说明

  • target_list:由多个target_el组成的列表。
  • target_el:单个目标元素,可以是表达式、别名、通配符*、函数调用等。
  • rop_bool_expr:使用比较运算符连接的两个表达式。
  • b_expr:表达式的具体形式,如算术表达式、字符串表达式等。
  • bool_expr1:括号内的bool_expr逻辑运算形式。

批量处理opt_bulk

语法格式

sql
opt_bulk::=
    /*EMPTY*/
|   BULK COLLECT

参数说明

  • /*EMPTY*/:BULK COLLECT子句为空,即不使用BULK COLLECT,查询结果将逐行处理。
  • BULK COLLECT:批量处理,将查询结果一次性加载到集合中,而不是逐行处理。

插入opt_into_list

语法格式

sql
opt_into_list::=
    INTO ident[,ident]...
|   /*empty*/

参数说明

  • INTO ident[,ident]...:将查询结果插入到一个或多个目标标识符(ident)中。
  • /*empty*/:INTO子句为空,即不使用INTO子句。

参数和标识符ident

语法格式

sql
ident::=
    : ColId
|   : ICONST
|   ColId
|   COLUMN
|   SELF
|   ISNULL
|   NOTNULL
|   ident . ColLabel
|   ident (func_params)
|   OVERLAPS (func_params)
|   ident (ALL expr_list)
|   ident (DISTINCT b_expr[,b_expr]...)
|   ident (*)
|   EXTRACT (YEAR FROM b_expr)
|   EXTRACT (MONTH FROM b_expr)
|   EXTRACT (DAY FROM b_expr)
|   EXTRACT (HOUR FROM b_expr)
|   EXTRACT (MINUTE FROM b_expr)
|   EXTRACT (SECOND FROM b_expr)
|   ident (position_list)
|   ident (b_expr FROM b_expr FOR b_expr)
|   ident (BOTH {b_expr FROM b_expr | FROM b_expr})
|   ident (LEADING {b_expr FROM b_expr | FROM b_expr})
|   ident (TRAILING {b_expr FROM b_expr | FROM b_expr})
|   ident ({b_expr FROM b_expr | FROM b_expr})

expr_list::=
    b_expr
|   expr_list USING b_expr

position_list::=
    b_expr IN b_expr

参数说明

  • ident:标识符,可以是列名、常量、关键字、函数调用、表达式等。
  • expr_list:表达式列表,后面跟随USING关键字和一个布尔表达式,用于指定额外的条件或参数。
  • position_list:指定一个值列表、子查询或表,来判断左侧的表达式是否与右侧的任何一个值相匹配。

FROM子句opt_from_clause

语法格式

sql
opt_from_clause::=
    /*EMPTY*/
|   FROM table_ref[,table_ref]...

table_ref::=
    relation_expr
|   relation_expr alias_clause
|   select_with_parens
|   select_with_parens alias_clause
|   (relation_expr)
|   (relation_expr) alias_clause
|   joined_table
|   (joined_table) alias_clause
|   TABLE (c_expr)
|   TABLE (c_expr) alias_clause
|   TABLE select_with_parens
|   TABLE select_with_parens alias_clause

relation_expr ::= 
    name_space [PARTITION (name_list) | SUBPARTITION (name_list)]
|   name_space '@' name

alias_clause ::= 
    AS ColId (name_list)
|   AS ColId
|   ColId (name_list)
|   ColId

参数说明

  • opt_from_clause:可选的FROM子句,允许为空。
  • table_ref:表引用,可以是表名、子查询、连接表等。
  • relation_expr:表名或表的分区引用,可以带有链接名。
  • alias_clause:别名子句,可以是简单的别名或带有列别名的复杂别名。

WHERE子句opt_where_clause

语法格式

sql
opt_where_clause::=
    /*EMPTY*/
|   WHERE bool_expr

参数说明

opt_where_clause:可选的WHERE子句,允许为空。

分组opt_group_clause

语法格式

sql
opt_group_clause::=
    GROUP BY group_item [,group_item]...
|   /*EMPTY*/

group_item::=
    b_expr
|   ROLLUP (group_item [,group_item]...)
|   CUBE (group_item [,group_item]...)
|   GROUPING SETS (group_item [,group_item]...)
|   group_item,group_item [,group_item]...
|   ( )

参数说明

  • GROUP BY group_item [,group_item]...:表示GROUP BY子句后面跟随一个或多个group_item,每个group_item之间用逗号分隔。
  • /* EMPTY */:GROUP BY子句可以被省略,不进行任何分组。
  • b_expr:表示一个简单的表达式,通常是列名或基于列的表达式。这是最常见的分组项形式。
  • ROLLUP :GROUP BY的扩展,n+1次分组统计,其中n为分组字段数,按照从右至左依次递减字段生成分组统计,即对每个分组结果再进行小计和总和。如ROLLUP(a,b)的分组为(a,b)、(a)、()三种情况,第一次将整体作为条件进行分组小计,第二次对分组统计的最后一个字段删减作为条件再进行分组小计,第三次再次从右至左删减字段作为条件进行分组小计即为无条件将整个表进行统计。
  • CUBE:GROUP BY的扩展,多字段分组时按照聚合字段排列组合进行分组统计并对每一种组合结果进行汇总统计。如CUBE(a,b)统计的分组为(a,b)、(a)、(b)、()情况。
  • GROUPING SETS:GROUP BY的扩展,无需所有分组字段的排列组合仅返回每个字段的分组小计。如GROUPING SETS(a,b)统计的分组为(a)、(b)情况。
  • group_item,group_item [,group_item]...:多个group_item的组合,类似于直接在GROUP BY子句中列出多个分组项。
  • ( ):空分组项,对整个表进行汇总,不分组。

HAVING子句opt_having_clause

语法格式

sql
opt_having_clause ::= 
    HAVING bool_expr
|   /* EMPTY */

参数说明

  • HAVING bool_expr:表示HAVING子句后面跟随一个布尔表达式(bool_expr),该表达式用于筛选分组后的结果。
  • /* EMPTY */:HAVING子句可以被省略,不对分组结果进行任何额外的筛选。

层次查询opt_connect_by

语法格式

sql
opt_connect_by ::= 
    CONNECT BY bool_expr START WITH bool_expr [KEEP bool_expr]
|   CONNECT BY NOCYCLE bool_expr START WITH bool_expr [KEEP bool_expr]
|   START WITH bool_expr CONNECT BY bool_expr [KEEP bool_expr]
|   START WITH bool_expr CONNECT BY NOCYCLE bool_expr [KEEP bool_expr]
|   CONNECT BY bool_expr [KEEP bool_expr]
|   CONNECT BY NOCYCLE bool_expr [KEEP bool_expr]

参数说明

  • CONNECT BY bool_expr:指定层次结构的连接条件,使用一个布尔表达式来定义父节点和子节点之间的关系。
  • START WITH bool_expr:指定层次结构的根节点,使用一个布尔表达式来确定层次结构的起点。
  • NOCYCLE:防止循环引用。当层次结构中可能存在循环时(即某个节点最终指向自己),使用NOCYCLE可以避免无限递归。
  • KEEP bool_expr:用于在层次结构中保留特定的值。

select_with_parens

语法格式

sql
select_with_parens ::= 
    (select_no_parens parallel_opt opt_wait)
|   (select_with_parens)
|   (with_clauses select_no_parens)

参数说明

select_with_parens:在SELECT语句外部添加括号。

并行选项parallel_opt

语法格式

sql
parallel_opt ::= 
    /* EMPTY */
|   PARALLEL ICONST

参数说明

  • /* EMPTY */:不设置并行选项。
  • PARALLEL ICONST:数据库查询弹射并发数,并发数的值和逻辑CPU相关,小于逻辑CPU数。

with_clauses

语法格式

sql
with_clauses::=
    WITH with_name AS select_with_parens
|   with_clauses  , with_name AS select_with_parens
|   WITH ProcDef ;

with_name::=
    ColId [( name_list )]

参数说明

  • WITH:关键字,用于引入一个或多个公用表表达式。
  • with_name:CTE的名称,用于在后续查询中引用这个临时结果集。它是一个标识符(ColId),可以带有可选的列名列表(name_list)。
  • AS select_with_parens:定义CTE的内容,即一个带括号的 SELECT 语句。这个 SELECT 语句的结果将作为CTE的临时结果集。
  • with_clauses:可以包含多个CTE,每个CTE用逗号分隔。多个CTE可以相互引用,但不能循环引用。
  • ProcDef:扩展语法,表示可以在WITH子句中定义过程或函数。

示例

使用HINT

两种不同的查询执行计划:

  • 使用HINT:/*+INDEX(tb_hint idx_hit)*/
  • 不使用HINT。

根据EXPLAIN语句的结果,对目标表tb_hint使用HINT,SQL语句的执行计划为BtIdxScan,表示数据库使用了B树索引,能够快速查找特定值。不使用HINT,SQL语句的执行计划为SeqScan,表示数据库使用了全表扫描。全表扫描会逐行读取整个表,直到找到符合条件的记录。这种方式在小表或没有合适索引时可能是合理的,但在大表上性能较差。

sql
SQL> CREATE TABLE tb_hint(id INT,name VARCHAR(20));  

SQL> CREATE INDEX idx_hit ON tb_hint(id); 

-- 使用HINT查看SQL的执行计划
SQL> EXPLAIN SELECT /*+INDEX(tb_hint idx_hit)*/* FROM tb_hint WHERE id=3;

plan_path | 
------------------------------------------------------------------------------
1   BtIdxScan[(1 1) cost=300,result_num=1](table=TB_HINT)(index=IDX_HIT)|

-- 默认情况下的SQL执行计划
SQL> EXPLAIN SELECT * FROM tb_hint WHERE id=3;

plan_path | 
------------------------------------------------------------------------------
1   SeqScan[(1 1) cost=0,result_num=1](table=TB_HINT)|

使用TOP

使用TOP 2返回排列最前面的2行数据。

sql
SQL> CREATE TABLE tb_top(id INT,name VARCHAR(20));

SQL> INSERT INTO tb_top VALUES(1,'one')(2,'two')(3,'three')(4,'four');

SQL> SELECT TOP 2 * FROM tb_top ORDER BY id DESC;

ID | NAME | 
------------------------------------------------------------------------------
4 | four|
3 | three|

使用DISTINCT

id列中有两个1,使用DISTINCT只返回一个1,消除查询结果中的重复行。

sql
SQL> CREATE TABLE tb_dis(id INT,name VARCHAR(20));

SQL> INSERT INTO tb_dis VALUES(1,'one')(1,'two')(3,'three')(4,'four');

SQL> SELECT DISTINCT id FROM tb_dis;

ID | 
------------------------------------------------------------------------------
1 |
3 |
4 |

BULK COLLECT批量处理方法

使用BULK COLLECT将查询结果批量加载到集合中,批量输出。

sql
SQL> CREATE TABLE tb_coll(id INT,name VARCHAR(20));

SQL> INSERT INTO tb_coll VALUES(1,'one')(2,'two')(3,'three');

SQL> DECLARE
    TYPE v_table IS VARRAY(10) OF VARCHAR;
    st v_table;
    BEGIN
      SELECT name BULK COLLECT INTO st FROM tb_coll ;
      FOR i IN st.FIRST..st.LAST
      LOOP
        SEND_MSG(st(i));
      END LOOP;
    END;
    /

-- 输出结果:
one
two
three

分组统计并过滤

使用WHERE关键字查询表中id > 10的数据,并对结果进行分组,对分组后的数据再使用HAVING关键字过滤id > 20的数据并输出结果。

sql
SQL> CREATE TABLE tb_grp_hav(id INT,name VARCHAR(20));

SQL> INSERT INTO tb_grp_hav VALUES(1,'a')(1,'b')(20,'c')(20,'d')(100,'e')(100,'f')(100,'g');

SQL> SELECT id FROM tb_grp_hav WHERE id > 10 GROUP BY id HAVING id > 20;

ID | 
------------------------------------------------------------------------------
100 |

指定分区名查询指定分区数据

使用范围分区将表tb_part_sel分成了三个部分vp1vp2vp3,查询vp1分区的数据。

sql
SQL> CREATE TABLE tb_part_sel(id INT,name VARCHAR(20))PARTITION BY RANGE(id) PARTITIONS(vp1 VALUES LESS THAN(100),vp2 VALUES LESS THAN(1000),vp3 VALUES LESS THAN(20000));

SQL> INSERT INTO tb_part_sel VALUES(1,'one')(100,'two')(10003,'three');

SQL> SELECT * FROM tb_part_sel PARTITION(vp1);

ID | NAME | 
------------------------------------------------------------------------------
1 | one|

GROUP BY的三种扩展方式

  • ROLLUP(department,gender)的分组为(department,gender)(department)()三种情况。
  • CUBE(department,gender)的分组为(department,gender)(department)(gender)()情况。
  • GROUPING SETS(department,gender)分组为(department)(gender)情况。
sql
SQL> CREATE TABLE tb_grp3(id INT PRIMARY KEY,name VARCHAR(15),department VARCHAR(10),salary NUMBER(8, 2),gender VARCHAR(10));

SQL> INSERT INTO tb_grp3 VALUES (1001, 'John', 'IT', 35000, 'Male');
INSERT INTO tb_grp3 VALUES (1002, 'Smith', 'HR', 45000, 'Male');
INSERT INTO tb_grp3 VALUES (1003, 'James', 'Finance', 50000, 'Male');
INSERT INTO tb_grp3 VALUES (1004, 'Mike', 'Finance', 50000, 'Male');
INSERT INTO tb_grp3 VALUES (1005, 'Linda', 'HR', 75000, 'Female');
INSERT INTO tb_grp3 VALUES (1006, 'Anurag', 'IT', 35000, 'Male');
INSERT INTO tb_grp3 VALUES (1007, 'Priyanla', 'HR', 45000, 'Female');
INSERT INTO tb_grp3 VALUES (1008, 'Sambit', 'IT', 55000, 'Female');
INSERT INTO tb_grp3 VALUES (1009, 'Pranaya', 'IT', 57000, 'Female');
INSERT INTO tb_grp3 VALUES (1010, 'Hina', 'HR', 75000, 'Male');
INSERT INTO tb_grp3 VALUES (1011, 'Warner', 'Finance', 55000, 'Female');

-- 仅GROUP BY
SQL> SELECT department,gender,COUNT(*) group_cou FROM tb_grp3 GROUP BY(department,gender);

DEPARTMENT | GENDER | GROUP_COU | 
------------------------------------------------------------------------------
Finance| Female| 1 |
Finance| Male| 2 |
HR| Female| 2 |
HR| Male| 2 |
IT| Female| 2 |
IT| Male| 2 |

-- ROLLUP
SQL> SELECT department,gender,COUNT(*) rollup_cou FROM tb_grp3 GROUP BY ROLLUP(department,gender);

DEPARTMENT | GENDER | ROLLUP_COU | 
------------------------------------------------------------------------------
Finance| Female| 1 |
Finance| <NULL>| 3 |
Finance| Male| 2 |
HR| Female| 2 |
HR| <NULL>| 4 |
HR| Male| 2 |
IT| Female| 2 |
<NULL>| <NULL>| 11 |
IT| <NULL>| 4 |
IT| Male| 2 |

-- CUBE
SQL> SELECT department,gender,COUNT(*) cube_cou FROM tb_grp3 GROUP BY CUBE(department,gender);

DEPARTMENT | GENDER | CUBE_COU | 
------------------------------------------------------------------------------
Finance| Female| 1 |
Finance| <NULL>| 3 |
Finance| Male| 2 |
HR| Female| 2 |
HR| <NULL>| 4 |
HR| Male| 2 |
IT| Female| 2 |
<NULL>| <NULL>| 11 |
IT| <NULL>| 4 |
IT| Male| 2 |
<NULL>| Female| 5 |
<NULL>| Male| 6 |

-- GROUPING SETS
SQL> SELECT department,gender,COUNT(*) group_set_cou FROM tb_grp3 GROUP BY GROUPING SETS(department,gender);

DEPARTMENT | GENDER | GROUP_SET_COU | 
------------------------------------------------------------------------------
Finance| <NULL>| 3 |
HR| <NULL>| 4 |
IT| <NULL>| 4 |
<NULL>| Female| 5 |
<NULL>| Male| 6 |

SELECT后支持比较表达式

1>1返回结果错误。

sql
SQL> SELECT 1>1 FROM dual;

EXPR1 |
------------------------------------------------------------------------------
F |

(1<=2 and 1<=3)返回结果正确。

sql
SQL> SELECT (1<=2 and 1<=3) FROM dual;

EXPR1 |
------------------------------------------------------------------------------
T |

查询使用函数表

将函数aa(1)返回的集合转换为表,使其可以被SELECT语句查询。

sql
-- 创建table类型
SQL> CREATE TYPE obj AS TABLE OF VARCHAR(100);
    /

-- 创建返回obj函数
SQL> CREATE FUNCTION aa(i INT) RETURN obj
          IS
            o obj:= obj();
          BEGIN
            o.EXTEND;
            o(o.COUNT):='123';
            o.EXTEND;
            o(o.COUNT):='234';
            RETURN o;
          END;
          /

-- 函数表为函数
SQL> SELECT * FROM TABLE(aa(1));

COLUMN_VALUE | 
------------------------------------------------------------------------------
123|
234|

-- 函数表为子查询
SQL> SELECT * FROM TABLE(SELECT aa(1) FROM dual);

COLUMN_VALUE | 
------------------------------------------------------------------------------
123|
234|

查询使用CONNECT BY LEVEL

说明:

LEVEL是伪层次列名,在树形结构中表示层级

sql
SQL> CREATE TABLE tb_level(id VARCHAR2(1));
SQL> INSERT INTO tb_level (id) VALUES ('a');
SQL> INSERT INTO tb_level (id) VALUES ('b');
SQL> INSERT INTO tb_level (id) VALUES ('c');

-- 树形结构:
a b c
SQL> SELECT id,level FROM tb_level CONNECT BY LEVEL < 2;
ID | EXPR1 |
------------------------------------------------------------------------------
a| 1 |
b| 1 |
c| 1 |

-- 树形结构:
  a        b       c
a b c    a b c   a b c
SQL> SELECT id,level FROM tb_level CONNECT BY LEVEL < 3;
ID | EXPR1 |
------------------------------------------------------------------------------
a| 1 |
a| 2 |
b| 2 |
c| 2 |
b| 1 |
a| 2 |
b| 2 |
c| 2 |
c| 1 |
a| 2 |
b| 2 |
c| 2 |

-- 构造连续数字
SQL> SELECT LEVEL FROM dual CONNECT BY LEVEL <=10;
EXPR1 |
------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |

-- 构造连续日期
SQL> SELECT TO_DATE('202403', 'yyyymm') + LEVEL AS FDATE FROM dual CONNECT BY LEVEL <= 10;
FDATE |
------------------------------------------------------------------------------
2024-03-02 00:00:00.000 AD |
2024-03-03 00:00:00.000 AD |
2024-03-04 00:00:00.000 AD |
2024-03-05 00:00:00.000 AD |
2024-03-06 00:00:00.000 AD |
2024-03-07 00:00:00.000 AD |
2024-03-08 00:00:00.000 AD |
2024-03-09 00:00:00.000 AD |
2024-03-10 00:00:00.000 AD |
2024-03-11 00:00:00.000 AD |

查询使用AS别名做WHERE筛选

说明:

在WHERE子句中,虚谷数据库支持使用别名,且和字段定义名相比,别名优先。这和Oracle、MySQL不同,两者均不支持在WHERE子句中使用别名。对于GROUP、ORDER BY、HAVING子句,三者均支持使用别名,其中虚谷数据库对别名优先,Oracle和MySQL对字段名优先。

sql
SQL> CREATE TABLE tb_as(id INT NOT NULL, interfaceid VARCHAR(100));
SQL> INSERT INTO tb_as(id, interfaceid) VALUES (5,'ww');
SQL> INSERT INTO tb_as(id, interfaceid) VALUES (1,'aa');
SQL> INSERT INTO tb_as(id, interfaceid) VALUES (4,'bb');

-- interface列别名为id,id列别名为actionid
SQL> SELECT interfaceid AS id,id AS actionid FROM tb_as WHERE actionid = 5;
ID |ACTIONID |
------------------------------------------------------------------------------
ww| 5 |

-- WHERE id = 5即原始的interface = 5,无结果返回
SQL> SELECT interfaceid AS id,id AS actionid FROM tb_as WHERE id = 5;
ID |ACTIONID |
------------------------------------------------------------------------------

SQL> SELECT interfaceid AS id, id AS actionid FROM tb_as GROUP BY id,actionid HAVING actionid < 5 ORDER BY actionid DESC;
ACTIONID |
------------------------------------------------------------------------------

bb| 4 |
aa| 1 |

使用LIMIT

创建一个名为tb_limit的表,并插入100条记录:

  • LIMIT 2:从tb_limit表中选择前2行记录。
  • LIMIT 2,2:跳过前2行,然后返回接下来的2行记录。
  • LIMIT 2 OFFSET 2:同LIMIT 2,2
  • LIMIT 10,1:跳过前10行,然后返回接下来的1行记录。
sql
-- 创建数据表
SQL> CREATE TABLE tb_limit(id INT, name VARCHAR(20));

-- 插入数据
SQL> BEGIN
     FOR i IN 1..100 LOOP
             INSERT INTO tb_limit VALUES(i, 'limit');
     END LOOP;
     END;
     /

-- 返回指定数据量
SQL> SELECT * FROM tb_limit LIMIT 2;

ID | NAME | 
------------------------------------------------------------------------------
1 | limit|
2 | limit|

-- 偏移指定条数后返回指定数据量
SQL> SELECT * FROM tb_limit LIMIT 2,2;

ID | NAME | 
------------------------------------------------------------------------------
3 | limit|
4 | limit|
  
SQL> SELECT * FROM tb_limit LIMIT 2 OFFSET 2;

ID | NAME | 
------------------------------------------------------------------------------
3 | limit|
4 | limit|
  
-- 子查询使用LIMIT
SQL> SELECT * FROM tb_limit WHERE id = (SELECT id FROM tb_limit LIMIT 10,1);

ID | NAME | 
------------------------------------------------------------------------------
11 | limit|