mysql數據庫中的查詢語句

1、select查詢語句

         Select查詢語句作用是從現存的一個或多個表中查看滿足條件的數據,selectel查詢支持條件過濾、分組、排序、合併、嵌套查詢等特性,完整的查詢語法如下:

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}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]
    [ORDER BY {col_name | expr | position}
      [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_name(argument_list)]
    [INTO OUTFILE 'file_name'
        [CHARACTER SET charset_name]
        export_options
      | INTO DUMPFILE 'file_name'
      | INTO var_name [, var_name]]
    [FOR UPDATE | LOCK IN SHARE MODE]
    ]

 選項說明:

    Select_expr:要查詢的字段,至少要有一個select_expr,如果要查詢所有的字段可以使用”*”代替,Select_expr也可以使用MySQL內部的函數,另外字段也可以使用別名

    Table_references:查詢數據來自的一個或者多個表

    Group by:代表分組,通常和聚合函數配合使用,如最大值max, 最小值min, 平均值avg, 個數count,求和sum

    Order by:表示查詢結果按照順序排列,默認是升序排列,可以指定DESC表明按照降序排列

    Having:一般是跟在group by子句之後,代表限制分組之後的結果

    Limit:用來限制查詢結果的顯示的條數

    INTO:代表將查詢結果寫入文件中或者定義的參數變量中

    For update:將查詢的數據行加上寫鎖,直到本事務提交爲止

    Lock in share mode:代表將查詢的數據行加上讀鎖,則其他的鏈接可以讀相同的數據但無法修改加鎖的數據

    ALL|Distinct:代表是否將查詢結果中完全重複的行都查詢出來,ALL是默認值代表都查詢出來,distinct代表重複行只顯示一次

   HIGH_PRIORITY:代表賦予讀操作較高的操作優先級

   STRAIGHT_JOIN:強制優化器在表連接操作時按照語句中from子句中的表的順序執行

   SQL_SMALL_RESULT] [SQL_BIG_RESULT:通常是和group by/distinct一起使用,作用是事先告訴優化器查詢結果是大還是小,以便優化器事先準備好將查詢結果存放在磁盤臨時表或者快速臨時表中以便後續操作

   SQL_BUFFER_RESULT:強制將查詢結果存入臨時表中

   SQL_CALC_FOUND_ROWS:要求查詢結果的同時計算結果的行數,以便後續通過SELECT FOUND_ROWS()直接獲取行數

   SQL_CACHE | SQL_NO_CACHE:是否直接從query cache中獲取查詢結果

2、select基本查詢

(1)單表基本查詢

# 查詢student表中的所有數據
mysql> select * from student;
# 查詢mysql的user表中的所有用戶的用戶名和主機
mysql> select user,host from mysql.user;
# 只查看查到的前兩個用戶的信息
mysql> select user,host from mysql.user limit 2;
# 查看student表中的所有數據只顯示sid最大的兩條數據
mysql> select * from student order by sid desc limit 2;

(2)單表關鍵字範圍匹配查詢

         IN關鍵字:用來查詢滿足指定範圍內的條件記錄,也可使用not in查詢不是指定範圍的數據。

# 查詢sid爲5到8的數據
mysql> select * from student where sid in (5,8);
# 查詢sid不在5和8之間的數據
mysql> select * from student where sid not in (5,8);

         BETWEEN AND:用法和IN類似,用來查詢某個範圍內的值,也可使用”NOT BETWEEN AND”查詢不再指定範圍內的值。

# 查詢sid爲5到8的數據
mysql> select * from student where sid BETWEEN 5 AND 8;
# 查詢sid不在5和8之間的數據
mysql> select * from student where sid NOT BETWEEN 5 AND 8;

         LIKE:LIKE用於通過通配符進行匹配查詢,like支持的通配符有”%”和”_”,”_”只能匹配一個字符。

# 查詢student表中name字段以s開頭的數據
mysql> select * from student where sname like "n%";
# 查詢student表中sname字段以d開頭且只有兩個字符的數據
mysql> select sid,sname from student where sname like "d_";

         IS NULL:查詢字段爲空的數據,也可使用”IS NOT NULL”查詢字段爲非空的值。

# 查詢student表中gender字段爲空的數據
mysql> select sname,gender from student where gender IS NULL;
# 查詢student表中gender字段部位空的數據
mysql> select sname,gender from student where gender IS NOT NULL;

(3)帶AND或OR的多條件查詢

         AND:AND用於連接多個查詢條件,AND操作符限定只有所有的條件滿足時纔會返回結果。

         OR:OR也用於連接多個查詢條件,OR操作符限定滿足其中一個條件是即可返回查詢結果。

# 查詢student表中sid爲5(包含5)到8(不包含8)之間的數據
mysql> select sid,sname from student where sid >= 5 and sid < 8;
# 查詢sid不再5到8之間的數據
mysql> select sid,sname from student where sid < 5 or sid > 8;

(4)查詢結果中不顯示重複數據

# 查詢student表的gender字段的值並不顯示重複行(默認值爲all,是顯示的)
mysql> select distinct gender from student;  

(5)查詢結果排序

         ORDER BY:order by用於對查詢的結果進行排序,也可以根據多個不同的字段對查詢結果進行排序;默認排序正序,如果要使用倒序排序需要在排序的字段後面加”desc’.

# 依據name字段對查詢的結果進行排序
mysql> select sid,sname from student order by sname;
# 對查詢出的字段依據sname字段倒序排序
mysql> select sid,sname from student order by sname desc;
# 查詢student中數據先依據sname倒序排序,在依據sid倒序排序
mysql> select sid,sname from student order by sname desc,sid desc;

(6)分組查詢

         分組查詢是對數據按照某個或多個字段進行分組,使用”GROUP BY 分組字段”對數據進行分組,使用”HAVING”指定滿足限定表達式條件。

         Group by關鍵字通常和聚合函數一起使用,如MAX()、MIN()、COUNT()、SUM()、AVG()、GROUP_COUCAT()。

# 依據sname字段對student表中的數據進行分組
mysql> select sname,COUNT(*) AS total from student GROUP BY sname;     
+-----------+-------+
| sname     | total |
+-----------+-------+
| dayi      |     2 |
| name_test |     2 |
……
+-----------+-------+
# 根據sname對student表分組查詢,並將每個sname的sid顯示出來
mysql> select sname,GROUP_CONCAT(sid) AS NAMES from student GROUP BY sname;
+-----------+-------+
| sname     | NAMES |
+-----------+-------+
| dayi      | 4,14  |
| dayi123   | 5,15  |
……
+-----------+-------+

    分組查詢中也可以使用條件限制,與普通查詢不同的時分組查詢的限制條件使用”HAVING”做條件限定。

# 根據sname對student表分組查詢,並將sname中sid數量爲1 的數據顯示出來
mysql>  select sname,GROUP_CONCAT(sid) AS NAMES from student GROUP BY sname HAVING COUNT(sid) = 1;
+-------+-------+
| sname | NAMES |
+-------+-------+
| aaa   | 21    |
+-------+-------+

    WITH ROLLUP:分組查詢中的”WITH ROLLUP”用於統計記錄的數量,會在所有查詢出的分組記錄之後增加一條記錄,該記錄計算查詢出所有記錄的總和。

# 會在查詢結果中插入一行,統計記錄數量
mysql> select sname,COUNT(*) AS total from student GROUP BY sname WITH ROLLUP;
+-----------+-------+
| sname     | total |
+-----------+-------+
| aaa       |     1 |
……
| NULL      |    11 |
+-----------+-------+
7 rows in set (0.00 sec)

    使用”GROUP BY”分組時,可以對多個字段分組,在”GROUP BU”後面跟需要分組的字段即可對多個字段分組;多字段分組是根據多字段的值來進行層次分組,分組層次從左到右,先按第一個地段分組,然後在第一個字段值相同的記錄中,再根據第二個字段的值進行分組。

# 先根據sname分組,再根據sid分組,並對分組的結果依據sid反向排序
mysql> select * from student group by sname,sid order by sid desc;

3、連接查詢

    在查詢時,當兩個或多個表中存在相同意義的字段時,可以通過這些字段對不同的表進行連接查詢;連接查詢時關係型數據庫中的主要查詢,主要包括內連接和外連接。

(1)內連接查詢

         內連接(INNER JOIN)是使用比較運算符進行表間某列數據的比較操作,並列出這些表中與連接條件向匹配的數據行。

# 通過dept_id關聯查詢出teacher表中的name,id以及student表中的name,id
mysql> select sid,sname,id,name from student,teacher where student.dept_id=teacher.dept_id;
+-----+-------+-----+-------+
| sid | sname | id  | name  |
+-----+-------+-----+-------+
|   2 | liyi  | 102 | carey |
+-----+-------+-----+-------+
1 rows in set (0.38 sec)
# 通過inner join 來關聯兩個表查詢,查詢結果一樣
mysql> select sid,sname,id,name from student inner join teacher on student.dept_id=teacher.dept_id;

(2)外連接查詢

         LEFT JOIN(左連接):返回包括在左表中的所有記錄和右表中連接字段相等的記錄

         RIGHT JOIN(右連接):返回包括右表中的所有記錄和左表中連接字段相等的記錄

         外連接查詢將查詢多個表中相關聯的行,相對於內連接外連接查詢出的數據還包含沒有關聯的行中數據;外連接分爲左外連接和左連接,右外連接和右連接。

# 左連接查詢,會列出左表中的所有數據,並列出右表中的所有數據
mysql> select sname,name from student left outer join teacher on student.dept_id=teacher.dept_id;
+-----------+-------+
| sname     | name  |
+-----------+-------+
| liyi      | carey |
| name_test | NULL  |
| dayi      | NULL  |
| dayi123   | NULL  |
+-----------+-------+
4 rows in set (2.33 sec)
# 列出右表(teacher)表中的所有數據,並列出左表中相匹配的數據
mysql> select sname,name from student right outer join teacher on student.dept_id=teacher.dept_id;               
+-------+-------+
| sname | name  |
+-------+-------+
| liyi  | carey |
+-------+-------+
1 rows in set (0.00 sec)

4、合併查詢結果

    在查詢時可以使用”UNION”或”UNION ALL”關鍵字將多條SELECT語句的查詢結果合併成單個結果集。在合併時,兩個表對應的烈數和數據類型必須相同。

    ”UNION”和”UNION ALL”的區別在於對查詢結果UNION去重,UNION ALL不去重

# 查詢teacher和teacher_backup中的所有數據併合並,使用union all合併不去重
mysql> select * from teacher UNION ALL select * from teacher_backup; 
+-----+-------+---------+
| id  | name  | dept_id |
+-----+-------+---------+
| 102 | carey |       2 |
|   2 | ruth  |       2 |
| 102 | carey |       2 |
+-----+-------+---------+
3 rows in set (0.00 sec)
# 使用union合併去重
mysql> select * from teacher UNION select * from teacher_backup;    
+-----+-------+---------+
| id  | name  | dept_id |
+-----+-------+---------+
| 102 | carey |       2 |
|   2 | ruth  |       2 |
+-----+-------+---------+
2 rows in set (0.00 sec)

    如果相對union語句的最後結果做排序或者limit限制,則需要將每個select語句用括號括起來,把order by或limit語句放在最後。

# 對查詢結果進行排序並顯只示兩條數據
mysql> (select * from teacher) UNION ALL (select * from teacher_backup) order by id limit 2;
+-----+-------+---------+
| id  | name  | dept_id |
+-----+-------+---------+
|   2 | ruth  |       2 |
| 102 | carey |       2 |
+-----+-------+---------+
2 rows in set (0.00 sec)

5、使用別名查詢

(1)爲表去別名查詢

         在查詢時如果表名很長或者執行一些特殊查詢時,爲了方便操作或者多次使用相同的表時,可以使用表的別名來帶起表名。使用表名的方法爲”表名 AS 表別名”

# 使用teacher表別名查詢數據
mysql> select tb.id from teacher AS tb where tb.id=102;
+-----+
| id  |
+-----+
| 102 |
+-----+
1 row in set (0.00 sec)

(2)爲字段取別名

         爲字段取別名原理同爲表去別名原理相似。

# 爲字段取別名查詢
mysql> select st.sname AS student_name,st.sid AS student_id from student AS st where st.sid<=3;
+--------------+------------+
| student_name | student_id |
+--------------+------------+
| liyi         |          2 |
| name_test    |          3 |
+--------------+------------+
2 rows in set (0.00 sec)

6、將查詢結果保存至文件或者變量中

    Mysql查詢結果默認是輸出到標準的輸出設備,mysql查詢結果也可以輸出到指定的文件中或變量中。Mysql將查詢結果存入定義的變量或者文件是通過”select …into”語句完成的。

    Select…INTO vat_list:將查詢結果存入定義的變量。

    Select…INTO OUTFILE:將查詢結果按一定的格式寫入到文件中

    Select…INTO DUMPFILE:將查詢結果以一行的格式寫入到文件中,且只能寫入一行

(1)將查詢結果寫入變量

    需要保證查詢結果返回一行,如果不返回數據則報no data錯誤,如果返回多行則報Result consisted of more than one row錯誤,當返回行數不確定時,可以用limit 1強制只返回一行。

# 將查詢結果寫入變量中,查詢結果只能有一行
mysql> select sname,sid into @x,@y from student where sid=1;
Query OK, 0 rows affected, 1 warning (0.00 sec)
# 查看保存的變量
mysql> select @x,@y;
+------+------+
| @x   | @y   |
+------+------+
| NULL | NULL |
+------+------+
1 row in set (0.00 sec)

(2)將查詢結果保存到文件中

         要將查詢結果保存到文件中時,在mysql配置中需要添加” secure_file_priv=/PATH/”,並要重啓mysql使配置生效;文件會創建在本地服務器上,所以要確保用戶能創建文件,而且該路徑下不能存在同名的文件,以免被覆蓋。

# 將查詢結果保存到”/tmp/ slect_student.txt”,並制定分隔符爲”,”,換行符爲回車
mysql> select sname,sid into outfile '/tmp/slect_student.txt' fields terminated by ',' optionally enclosed by "" lines terminated by '\n' from course.student;
Query OK, 11 rows affected (0.18 sec)
# 使用dumpfile時只能保存查詢出的一行數據
mysql> select sid,sname into dumpfile '/tmp/select_student2.txt' from course.student limit 1;
Query OK, 1 row affected (0.01 sec)

7、mysql子查詢

         子查詢是指一個查詢語句嵌套在另一個查詢語句內部的查詢。子查詢中常用的操作符有ANY(SOME)、ALL、IN、EXISTS,子查詢也可以添加到SELECT、UPDATE和DELETE語句中,並且可以多層嵌套,子查詢中也可使用比較運算符。

(1)帶ANY、SOME關鍵字的子查詢

         ANY和SOME作用相同,表示滿足其中任一條件,它們允許創建一個表達式對子查詢的返回值列表進行比較,只要滿足內存查詢的任何一個比較條件,就返回一個結果作爲外層子查詢的條件。

# 只有student中的sid大於student02中的任一一個sid就返回查詢的數據
mysql> select sid,sname from student where sid > any (select sid from student02);
+-----+-----------+
| sid | sname     |
+-----+-----------+
|  13 | name_test |
|  14 | dayi      |
|  15 | dayi123   |
|  20 | dy        |
| 100 | test_name |
| 101 | ly        |
+-----+-----------+

(2)帶ALL關鍵字的子查詢

使用ALL時需要同時滿足所有內層查詢的條件

# 使用all時student中的sid大於student02中的所有的sid時才返回數據
mysql> select sid,sname from student where sid > all (select sid from student02);   
+-----+-----------+
| sid | sname     |
+-----+-----------+
| 100 | test_name |
| 101 | ly        |
+-----+-----------+

(3)帶EXISTS關鍵字的子查詢

         EXISTS關鍵字後面的參數是一個任意的子查詢,系統對子查詢進行運算以判斷它是否返回行,如果至少返回一行,nameEXISTS的結果爲True,此時外層的查詢語句將進行查詢。如果子查詢沒有返回任何行,則EXISTS的返回結果爲false,外層語句將不進行查詢。NOT EXISTS作用與EXISTS作用相反

# 由於存在student02中存在sid=20的數據,所以會返回查詢結果
mysql> select sid,sname from student where sid >= 20 and exists (select sid from student02 where sid=15);
+-----+-----------+
| sid | sname     |
+-----+-----------+
|  20 | dy        |
| 100 | test_name |
| 101 | ly        |
+-----+-----------+

(4)帶in關鍵字的子查詢

         使用IN關鍵字進行子查詢時,內存查詢語句僅需返回一列數據,返回的數據將提供給外層查詢語句進行比較操作。NOT IN作用與IN相反。

# in關鍵字查詢相當於求交集
mysql> select sid,sname from student where sid in (select sid from student02);     
+-----+-----------+
| sid | sname     |
+-----+-----------+
|  12 | liyi      |
|  13 | name_test |
|  14 | dayi      |
|  15 | dayi123   |
|  20 | dy        |
+-----+-----------+

(5)帶比較運算符的子查詢

         在子查詢時可以使用比較運算符如”<”,”<=”,”=”,”>”,”>=”和”!=”等。

# 查看報了’carey’老師的課程的學生。
mysql> select sid,sname from student where dept_id=(select dept_id from teacher where name='carey');       
+-----+-------+
| sid | sname |
+-----+-------+
|   2 | liyi  |
|  12 | liyi  |
+-----+-------+

8、創建視圖

    視圖是一種虛擬表,建立在基本表的基礎上,通過關聯一個表或者多個表來獲取多個表中需要的字段,視圖只是用來查詢數據並不能用來存儲數據信息。

(1)創建視圖的語句

 CREATE 
          [OR REPLACE]
          [ALGORIHM = {UNDEFINED | MERGE | TEMPTABLE}]
          [DEFINER = { user | CURRENT_USER }]
          [SQL SECURITY { DEFINER | INVOKER }]
          VIEW view_name [(column_list)]
          AS select_statement
          [WITH [CASCADED | LOCAL] CHECK OPTION]

各選項說明:

         Or replace:關鍵詞表示當創建的視圖已經存在時,執行替換命令

         Select_statement:子句則是創建視圖的select語句,可以是從表中查詢數據,也可以從其他視圖中查詢數據

(1)創建視圖

# 創建視圖,視圖中的主要信息爲student表中的sid小於10的sname,sid
mysql> create view student_view as select sid,sname from student where sid < 10;
Query OK, 0 rows affected (0.00 sec)
# 查詢視圖中的信息
mysql> select * from student_view where sid=2;
+-----+-------+
| sid | sname |
+-----+-------+
|   2 | liyi  |
+-----+-------+
1 row in set (0.00 sec)
# 使用or replace覆蓋創建的視圖
mysql> create or replace view student_view as select sid,sname from student where sid >= 20;

(2)創建視圖的其他選項

         當視圖被創建之後,則其定義就已經固定不會再改變,後續對源表增加的字段不會成爲視圖的一部分,而後續對錶刪除字段則會導致查詢視圖失敗。

    Order by子句在創建視圖過程中是允許的,但當後續的查詢視圖的語句中有自己的order by子句時則會被忽略掉。

    視圖在滿足特定條件時是可以執行insert/update/delete語句的,條件就是視圖中的每一行和視圖對應的表中的每行數據都能一一對應起來。

# 在創建的視圖中插數入據,原表中也會插入數據
mysql> insert into student_view values(100,'test_name');
Query OK, 1 row affected (0.01 sec)
# 更新視圖中數據,同時視圖所對應的原表中的數據也會更改
mysql> update student_view set sname='abcd' where sid=21;
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
# 通過視通刪除數據,同時視圖對應的原表中的數據也會被刪除
mysql> delete from student_view where sid=21;
Query OK, 1 row affected (0.00 sec)

(3)修改視圖

         視圖被創建後,也可通過”alter view”語句來修改視圖的定義,作用和”create or replace view”語句相同。

# 修改視圖
mysql> alter view student_view as select sid,sname from student where sid = 2;
Query OK, 0 rows affected (0.00 sec)

(4)刪除視圖

         刪除視圖時通過”drop view語句來刪除”。

# 刪除創建的視圖
mysql> drop view student_view;
Query OK, 0 rows affected (0.00 sec)
# 加了”if exists”再次刪除時不會報錯
mysql> drop view if exists student_view;
Query OK, 0 rows affected, 1 warning (0.00 sec)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章