1 select語句介紹
select語句是值從現存的一個或多個表中查看滿足條件的數據,其基本語法如下:
Syntax:
SELECT
[ALL | DISTINCT | DISTINCTROW ]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT] [SQL_BIG_RESULT] [SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE] [SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[PARTITION partition_list]
[WHERE where_condition]
[GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
[HAVING where_condition]
[WINDOW window_name AS (window_spec)
[, window_name AS (window_spec)] ...]
[ORDER BY {col_name | expr | position}
[ASC | DESC], ... [WITH ROLLUP]]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[INTO OUTFILE 'file_name'
[CHARACTER SET charset_name]
export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name]]
[FOR {UPDATE | SHARE} [OF tbl_name [, tbl_name] ...] [NOWAIT | SKIP LOCKED]
| LOCK IN SHARE MODE]]
2 select語句關鍵詞介紹
select_expr關鍵詞代表要查詢的字段,至少要有一個select_expr,或者如果是查詢所有字段,則用*號代替;
table_reference關鍵詞代表查詢數據來自的一個或多個表;
where子句代表只查詢滿足條件的表數據,如果沒有 where子句則代表查詢表中所有的數據;
where條件中不能使用select-expr中定義的字段別名,因為語句執行順序是where在select之前,所以where在執行時字段別名未知;
form table_references子句中指定表名,tbl_name也可以指定別名,當涉及的表不在當前的數據庫中,需要使用db_name.tbl_name來指定表和所在的數據庫名;
mysql> select t1.name,t2.salary from employee as t1,info as t2 where t1.name=t2.name;
mysql> select t1.name,t2.salary from employee t1,info t2 where t1.name=t2.name;
當多個表中有相同的字段名,且需要查詢出來時,需要在select_expr中能夠使用tbl_name.column_name來 顯式指定要查詢哪個表的字段;
group by子句代表分組,通常聚合函數配合使用,如max, min, avg, count, sum;
mysql> select sum(score) from scores;
mysql> select sid,count(*),max(score),min(score),avg(score),sum(score) from scores group by sid;
having子句一般是跟在group by子句之后,代表限制分組之后的結果;
mysql> select user,max(salary) from users group by user having max(salary)>10;
order by子句表示查詢結果按照順序排列,默認是升序排列,可以指定desc表名按照降序排列;
limit子句用來限制查詢結果的條數,其后可以帶兩位大於0的正數,第一位代表offset,第二位代表取多少行,一般情況下,limit和order by子句配合使用;
select * from tbl order by id limit 5;
select * from tbl order by id limit 5,10; ## 返回rows 6-15
select...into語句代表將查詢結果寫入文件中或者定義的參數變量中;
for update關鍵詞代表將查詢的數據行加上寫鎖,直到本事物提交為止;
lock in share mode關鍵詞代表將查詢的數據行加上讀鎖,則其他的鏈接可以讀相同的數據但無法修改加鎖的數據;
all/distinct關鍵詞代表是否將查詢結果中完全重復的行都查詢出來,all是默認值代表都查詢出來,指定distinct代表重復行只顯示一次;
high_priority代表賦予讀操作較高的操作優先級;
max_statement_time=N子句代表設置語句執行超時時間(毫秒);
straight_join關鍵詞代表強制優化器在表連接操作時按照語句中from子句中的表的順序執行;
sql_big_result/sql_small_result通常是和group by/distinct一起使用,其作用是事先告訴優化器查詢結果是大還是小米,以便優化器事先准備好將查詢結果存放在磁盤臨時表或者快速臨時表中以便后續操作;
sql_buffer_result強制將查詢結果存入臨時表中;
sql_calc_found_rows關鍵詞代表要求查詢結果的同時計算結果的行數,以便后續通過select found_rows()直接獲取行數;
sql_cache/sql_no_cache代表是否直接從query cache中獲取查詢結果。
mysql> select count(*),count(all sid),count(distinct sid) from scores;
+----------+----------------+---------------------+
| count(*) | count(all sid) | count(distinct sid) |
+----------+----------------+---------------------+
| 5 | 5 | 2 |
3 select...into語句
select...into語句代表將查詢結果存入定義的變量或文件中。
select...into var_list將查詢結果存入定義的變量;select...into outfile將查詢結果按照一定的格式寫入到文件中;select...into dumpfile將查詢結果以一行的格式寫入到文件中且只能寫入一行。
select...into使用注意事項
- 當使用存入變量方法時,需要保證查詢結果返回一行,如果不返回數據則報
no data錯誤,如果返回多行則報result consisted of more than one row錯誤,當返回行數不確定是,可以用limit 1強制只返回一行; - 使用
select..into outfile 'file_name'時,文件會創建在本地服務器上,所以要確保用戶能創建文件,而且此file_name不能已經存在在服務器上以免覆蓋其他文件。
SELECT sid,sname,sex INTO OUTFILE '/tmp/students.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM students;
## ERROR 1290 (HY000): The MySQL server is running with the --secure-file-priv option so it cannot execute this statement
## My.ini配置文件中添加secure_file_priv=/tmp/后重啟再執行,成功
mysql> select * into dumpfile '/tmp/students3.txt' from students;
mysql> select * into dumpfile '/tmp/students4.txt' from students limit 1;
Query OK, 1 row affected (0.00 sec)
4 select語句中的表連接
當select語句中涉及到多表查詢結果時,就會用到表連接操作。
mysql> help join
table_factor:
tbl_name [PARTITION (partition_names)]
[[AS] alias] [index_hint_list]
| table_subquery [AS] alias [(col_list)]
| ( table_references )
join_table:
table_reference [INNER | CROSS] JOIN table_factor [join_condition]
| table_reference STRAIGHT_JOIN table_factor
| table_reference STRAIGHT_JOIN table_factor ON conditional_expr
| table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition
| table_reference NATURAL [INNER | {LEFT|RIGHT} [OUTER]] JOIN table_factor
join_condition:
ON conditional_expr
| USING (column_list)
在MySQL中,join/inner join/cross join三者的作用是一樣的;
join語句中表別名的用法:
SELECT t1.name, t2.salary
FROM employee AS t1 INNER JOIN info AS t2 ON t1.name = t2.name;
SELECT t1.name, t2.salary
FROM employee t1 INNER JOIN info t2 ON t1.name = t2.name;
from子句后面還可以跟子查詢,但子查詢必須帶別名:
SELECT * FROM (SELECT 1, 2, 3) AS t1;
當inner join或者表之間用逗號隔開,且沒有表之間的關聯字段,則代表結果是兩者的笛卡爾積;
conditional_expr子句一般代表指定兩個表之間的關聯條件,而where條件中指定查詢結果的篩選條件;
straight_join和join的用法大致相同,唯一不同是確保左表是先被讀取的,以保證優化器的讀取順序。
select語句中的表連接示例:
SELECT * FROM students, scores; ##沒有關聯條件,表示笛卡爾積
SELECT * FROM students INNER JOIN scores ON students.sid=scores.sid;
SELECT * FROM students LEFT JOIN scores ON students.sid=scores.sid;
SELECT * FROM students LEFT JOIN scores USING (sid);
SELECT * FROM students LEFT JOIN students2 ON students.sid=students2.sid
LEFT JOIN scores ON students2.sid=scores.sid;
5 select語句中的union
union用來將多個select語句的執行結果合並成一個結果。
mysql> help union
Syntax:
SELECT ...
UNION [ALL | DISTINCT] SELECT ...
[UNION [ALL | DISTINCT] SELECT ...]
-
第一個
select語句的column_name會被當做最后查詢結果的列名,接下來的每個select語句所一一對應的列應該和第一個語句的列的數據類型最好保持一致 -
默認情況下
union語句會把最終結果中的重復行去掉,這和增加distinct這個關鍵詞的作用一樣,如果使用union all則代表最終結果中的重復行保留
select...union使用示例:
mysql> select sid,sname from students
union
select sid,gender from students2;
+-----+-------+
| sid | sname |
+-----+-------+
| 3 | a |
| 4 | a |
| 5 | a |
| 1 | abc |
| 2 | abc |
| 1 | -2 |
| 2 | -1 |
如果對union語句的最后結果做排序或者limit限制,則需要將每個select語句用括號括起來,把order by或limit語句放在最后:
(Select sid,sname from students)
Union
(Select sid,sname from students2)
order by sid limit 2;
+------+-------+
| sid | sname |
+------+-------+
| 1 | aaa |
| 2 | ccc |
+------+-------+
2 rows in set (0.00 sec)
