[TOC] # SELECT SELECT 的语法相对比较复杂。本节首先会介绍普通的 SELECT 语法结构,然后介绍集合类 SELECT 的语法结构。 ## SIMPLE SELECT ### 描述 该语句用于查询表中的内容。 ### 格式 ~~~ simple_select: SELECT [/*+ hint statement */] [ALL | DISTINCT | UNIQUE | SQL_CALC_FOUND_ROWS] select_expr_list FROM from_list [WHERE condition] [GROUP BY group_expression_list [WITH ROLLUP] [HAVING condition]] [ORDER BY order_expression_list] [limit_clause] [FOR UPDATE] select_expr: table_name.* | table_alias_name.* | expr [[AS] column_alias_name] from_list: table_reference [, table_reference ...] table_reference: simple_table | joined_table simple_table: table_factor [partition_option] [[AS] table_alias_name] | (select_stmt) [AS] 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] limit_clause: LIMIT {[offset,] row_count |row_count OFFSET offset} ~~~ ### 参数解释 <table data-tag="table" id="table-ie3-6bk-53o" class="table"><colgroup span="1" width="301" data-tag="col" id="col-2j0-39k-c64" colwidth="1*" colnum="1" colname="col1" style="width:50%" class="col"></colgroup><colgroup span="1" width="404" data-tag="col" id="col-xan-elv-ejk" colwidth="1*" colnum="2" colname="col2" style="width:50%" class="col"></colgroup><thead id="thead-uep-20e-qkr" class="thead"><tr id="tr-hx3-ffw-76h"><th id="td-8qg-se1-3yg"><p id="p-5nn-0bh-wnf">参数</p></th><th id="td-1bc-9ag-vfz"><p id="p-g4v-qh4-44s">描述</p></th></tr></thead><tbody data-tag="tbody" id="tbody-co5-ngx-v7v" class="tbody"><tr data-tag="tr" id="tr-7n3-qn1-u8d" class="tr"><td data-tag="td" id="td-2f8-sqi-uj5" class="td"><p data-tag="p" id="p-p7b-dlx-1vo" class="p">ALL | DISTINCT | UNIQUE |&nbsp;SQL_CALC_FOUND_ROWS</p></td><td data-tag="td" id="td-zlc-cgw-gl7" class="td"><p id="p-04o-kjj-3gp">在数据库表中,可能会包含重复值。</p><ul id="ul-k2r-tea-7be"><li id="li-j52-iaz-dyx"><p id="p-a3q-uyh-no7">指定“DISTINCT”,则在查询结果中相同的行只显示一行;</p></li><li id="li-862-led-c67"><p id="p-vla-3ws-xzl">指定“ALL”,则列出所有的行;</p></li><li id="li-6d1-wdq-0bg"><p id="p-nht-6de-9ub">指定“SQL_CALC_FOUND_ROWS”,则不输出数据,只返回数据行数;</p></li><li id="li-myk-w10-nta"><p id="p-rjj-56b-prc">不指定时,默认为“ALL”。</p></li></ul></td></tr><tr data-tag="tr" id="tr-7mw-9lo-81f" class="tr"><td data-tag="td" id="td-z8b-84u-lcw" class="td"><p data-tag="p" id="p-acg-k55-da2" class="p">select_expr </p></td><td data-tag="td" id="td-km9-2wn-xpy" class="td"><p data-tag="p" id="p-4rs-gkc-kuk" class="p">列出要查询的表达式或列名,用“,”隔开。也可以用“*”表示所有列。</p></td></tr><tr data-tag="tr" id="tr-ew7-7fq-djg" class="tr"><td data-tag="td" id="td-sck-elr-5if" class="td"><p data-tag="p" id="p-1mk-2iw-5ma" class="p">AS othername</p></td><td data-tag="td" id="td-xdq-a1c-dpl" class="td"><p data-tag="p" id="p-na3-zbi-1we" class="p">为输出字段重新命名。</p></td></tr><tr data-tag="tr" id="tr-vlq-jdb-ddi" class="tr"><td data-tag="td" id="td-xe6-n1f-o0x" class="td"><p data-tag="p" id="p-5vy-cyo-5ok" class="p">FROM table_references</p></td><td data-tag="td" id="td-8cy-k0r-qym" class="td"><p data-tag="p" id="p-bs2-9cb-act" class="p">指名了从哪个表或哪些表中读取数据(支持多表查询)。</p></td></tr><tr data-tag="tr" id="tr-34d-z3c-gn9" class="tr"><td data-tag="td" id="td-33u-ezg-4zc" class="td"><p data-tag="p" id="p-xo2-3zu-dby" class="p">WHERE where_conditions</p></td><td data-tag="td" id="td-ns1-ty9-mpr" class="td"><p data-tag="p" id="p-1kk-maf-510" class="p">可选项,WHERE 字句用来设置一个筛选条件,查询结果中仅包含满足条件的数据。where_conditions 为表达式。</p></td></tr><tr data-tag="tr" id="tr-vhy-sdm-sb9" class="tr"><td data-tag="td" id="td-wag-xex-4ag" class="td"><p data-tag="p" id="p-iep-v4q-s63" class="p">GROUP BY group_by_list</p></td><td data-tag="td" id="td-pbb-5c2-vfe" class="td"><p data-tag="p" id="p-jbu-bb2-zvb" class="p">用于进行分类汇总。</p></td></tr><tr data-tag="tr" id="tr-fwi-96f-vbl" class="tr"><td data-tag="td" id="td-yhn-u5y-qoz" class="td"><p data-tag="p" id="p-pay-kgt-56n" class="p">HAVING search_confitions</p></td><td data-tag="td" id="td-irw-xv2-1rg" class="td"><p data-tag="p" id="p-plj-xnr-5s2" class="p">HAVING 字句与 WHERE 字句类似,但是 HAVING 字句可以使用累计函数(如 SUM,AVG 等)。</p></td></tr><tr data-tag="tr" id="tr-kch-4xx-fdl" class="tr"><td data-tag="td" id="td-byd-yuu-zpc" class="td"><p data-tag="p" id="p-edl-9tq-41t" class="p">ORDER BY order_list</p><p id="p-57v-rj8-grq">order_list :</p><p id="p-86p-o0s-53g">colname [ASC | DESC] [,colname [ASC | DESC]…]</p></td><td data-tag="td" id="td-lhr-c0q-vln" class="td"><p data-tag="p" id="p-hbx-o40-n58" class="p">用来按升序(ASC)或者降序(DESC)显示查询结果。不指定 ASC 或者 DESC 时,默认为 ASC。</p></td></tr><tr data-tag="tr" id="tr-8q5-68j-dj6" class="tr"><td id="td-7ox-gsd-qui"><p id="p-iwc-u8f-31h">[LIMIT {[offset,] row_count |row_count OFFSET offset}]</p></td><td id="td-jp5-otv-cxi"><p id="p-zuk-ayj-gji">强制 SELECT 语句返回指定的记录数。</p><p id="p-e8f-zfr-83u">LIMIT 接受一个或两个数字参数。参数必须是一个整数常量。</p><ul id="ul-lmr-vzu-0hd"><li id="li-mhl-tca-qsj"><p id="p-9lc-c4r-al7">如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。初始记录行的偏移量是 0(而不是 1)。</p></li><li id="li-lwk-ht5-box"><p id="p-zt1-x0p-vew">如果只给定一个参数,它表示返回记录行的最大数目,偏移量为0。</p></li></ul></td></tr><tr data-tag="tr" id="tr-fxd-1p0-9hq" class="tr"><td data-tag="td" id="td-vdf-15c-0yd" class="td"><p data-tag="p" id="p-l87-nut-u1o" class="p">FOR UPDATE</p></td><td data-tag="td" id="td-7d1-1n6-75f" class="td"><p data-tag="p" id="p-a8k-f4o-1io" class="p">对查询结果所有行上排他锁,以阻止其他事务的并发修改,或阻止在某些事务隔离级别时的并发读取。</p></td></tr><tr data-tag="tr" id="tr-6fs-eqs-fep" class="tr"><td data-tag="td" id="td-zjb-n0v-8za" class="td"><p data-tag="p" id="p-u52-gnv-w2u" class="p">PARTITION(partition_list)</p></td><td data-tag="td" id="td-8ge-wyo-93f" class="td"><p data-tag="p" id="p-uio-ui0-sic" class="p">指定查询表的分区信息。例如:partition(p0,p1…)</p></td></tr></tbody></table> ### 示例 以如下表 a 为例。 ![](https://img.kancloud.cn/a5/1e/a51e99712b1ff92159127b168d85d67c_243x119.png) * 从表 a 中读取 name 数据。 ~~~ SELECT name FROM a; ~~~ ![](https://img.kancloud.cn/7e/bc/7ebcc7e95ea61820bd4c55f525985eef_265x151.png) * 在查询结果中对 name 进行去重处理。 ~~~ SELECT DISTINCT name FROM a; ~~~ ![](https://img.kancloud.cn/75/ff/75ff1b1e8fbbb0b057630643c2cc6de8_301x131.png) * 从表 a 中查询 id,name,num,然后把 num 列除以2输出,输出的列名为 avg。 ~~~ SELECT id, name, num/2 AS avg FROM a; ~~~ ![](https://img.kancloud.cn/bf/86/bf86f7d64e5e8198fa1bdf986c78484b_252x145.png) * 从表 a 中根据筛选条件“ name = 'a' ” ,输出对应的 id 、name 和 num 。 ~~~ SELECT id, name, num FROM a WHERE name = 'a'; ~~~ ![](https://img.kancloud.cn/cf/59/cf5979c758a3956a15e5f91970edaef7_251x132.png) * 从表 a 中查询 id,name,按照 name 分组对 num 求和,并输出。 ~~~ SELECT id, name, SUM(num) FROM a GROUP BY name; ~~~ ![](https://img.kancloud.cn/ea/07/ea07fb391e79f186b0d62e5fb2ce4568_279x131.png) * 从表 a 中查询 id,name,按照 name 分组对 num 求和,查询 num 总和小于160的行,并输出。 ~~~ SELECT id, name, SUM(num) as sum FROM a GROUP BY name HAVING SUM(num) < 160; ~~~ ![](https://img.kancloud.cn/20/fa/20fa8eac8a2d7065ba3575ab4b6170ca_250x119.png) * 从表 a 中查询 id,name,num,根据 num 按升序(ASC)输出查询结果。 ~~~ SELECT * FROM a ORDER BY num ASC; ~~~ ![](https://img.kancloud.cn/25/c0/25c08a990a8102df998533bdb66b0d44_275x150.png) 从表 a 中查询 id,name,num,根据 num 按降序(DESC)输出查询结果。 ~~~ SELECT * FROM a ORDER BY num DESC; ~~~ 从表 a 中查询 id,name,num,使用 LIMIT强制从第2行开始,返回表 a 的两行结果。 ~~~ SELECT * FROM a LIMIT 1,2; ~~~ ![](https://img.kancloud.cn/ac/b6/acb682408281c9b26a53a33c9e2d8b43_241x129.png) ## 集合类 SELECT ### 描述 该语句用于对多个 SELECT 查询的结果进行 UNION,MINUS,INTERSECT。 ### 格式 ~~~ select_clause_set: simple_select [ UNION | UNION ALL | EXCEPT | INTERSECT] select_clause_set_left [ORDER BY sort_list_columns] [limit_clause] select_clause_set_right: simple_select | select_caluse_set ~~~ ### 参数解释 <table data-tag="table" id="table-98i-yej-2kf" class="table"><colgroup span="1" width="323" data-tag="col" id="col-s68-4ab-o2t" colwidth="1*" colnum="1" colname="col1" style="width:50%" class="col"></colgroup><colgroup span="1" width="358" data-tag="col" id="col-7ut-ha0-50t" colwidth="1*" colnum="2" colname="col2" style="width:50%" class="col"></colgroup><thead id="thead-np0-6sb-jwl" class="thead"><tr id="tr-bku-80u-52g"><th id="td-e1b-071-b1k"><p id="p-e67-60q-b3k">参数</p></th><th id="td-b7f-04x-91r"><p id="p-yud-flc-eoj">描述</p></th></tr></thead><tbody data-tag="tbody" id="tbody-kop-rof-ses" class="tbody"><tr data-tag="tr" id="tr-lji-49b-02o" class="tr"><td data-tag="td" id="td-gf6-sra-x4a" class="td"><p data-tag="p" id="p-vcj-27p-xb3" class="p">UNION ALL</p></td><td data-tag="td" id="td-v4a-ztu-6ec" class="td"><p data-tag="p" id="p-u17-x8v-art" class="p">合并两个查询的结果</p></td></tr><tr data-tag="tr" id="tr-u1x-qmu-bmn" class="tr"><td data-tag="td" id="td-kya-q53-cgl" class="td"><p data-tag="p" id="p-96l-1mw-mdr" class="p">UNION</p></td><td data-tag="td" id="td-en0-7jn-9pe" class="td"><p data-tag="p" id="p-d45-bg5-hft" class="p">合并两个查询的结果,并去重</p></td></tr><tr data-tag="tr" id="tr-2cu-iwp-gfx" class="tr"><td data-tag="td" id="td-as0-8c2-mza" class="td"><p data-tag="p" id="p-no3-awt-sxg" class="p">EXCEPT</p></td><td data-tag="td" id="td-dgh-zgo-jd6" class="td"><p data-tag="p" id="p-zmi-59q-x34" class="p">从左查询结果集中去重出现在右查询中的结果,并去重</p></td></tr><tr data-tag="tr" id="tr-tqg-eg2-0as" class="tr"><td data-tag="td" id="td-ifh-xyp-izy" class="td"><p data-tag="p" id="p-xex-uga-wlw" class="p">INTERSECT</p></td><td data-tag="td" id="td-w7s-re2-6mw" class="td"><p data-tag="p" id="p-uch-1km-l90" class="p">保留左查询结果集中出现在右查询中的结果,并去重</p></td></tr></tbody></table> ### 示例 以如下两表的数据为例: ~~~ create table t1 (c1 int, c2 int); create table t2 (c1 int, c2 int); insert into t1 values (1, -1), (2, -2); insert into t2 values (1, 1), (2, -2), (3, 3); ~~~ * 计算 T1, T2 的所有的记录 ~~~ SELECT C1, C2 FROM T1 UNION ALL SELECT C1, C2 FROM T2; +------+------+ | C1 | C2 | +------+------+ | 1 | -1 | | 2 | -2 | | 1 | 1 | | 2 | -2 | | 3 | 3 | +------+------+ ~~~ * 计算 T1, T2 的去重后的所有记录 ~~~ SELECT C1, C2 FROM T1 UNION SELECT C1, C2 FROM T2; +------+------+ | C1 | C2 | +------+------+ | 1 | -1 | | 2 | -2 | | 1 | 1 | | 3 | 3 | +------+------+ ~~~ * 计算 T1 和 T2 的交集 ~~~ SELECT C1, C2 FROM T1 INTERSECT SELECT C1, C2 FROM T2; +------+------+ | C1 | C2 | +------+------+ | 2 | -2 | +------+------+ ~~~ * 计算 T1 和 T2 的差集 ~~~ SELECT C1, C2 FROM T1 EXCEPT SELECT C1, C2 FROM T2; +------+------+ | C1 | C2 | +------+------+ | 1 | -1 | +------+------+ ~~~ * 取 T1 和 T2 并集中 C2 排序最大的前两行 ~~~ SELECT C1, C2 FROM T1 UNION SELECT C1, C2 FROM T2 ORDER BY C2 DESC LIMIT 2; +------+------+ | C1 | C2 | +------+------+ | 3 | 3 | | 1 | 1 | +------+------+ ~~~