1. 程式人生 > >mysql資料庫查詢

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)