1. 程式人生 > >MySQL(2)資料庫 表的查詢操作

MySQL(2)資料庫 表的查詢操作

 來源參考https://www.cnblogs.com/whgk/p/6149009.html

跟著源部落格敲一遍可以加深對資料庫的理解,同時對其中一些程式碼做一些改變,可以驗證自己的理解。

本文改動了其中的一些程式碼和內容,刪除了其中比較簡單的內容,以便於操作和理解。

 

一、單表查詢

建立查詢環境

CREATE TABLE fruits(
f_id CHAR(10) NOT NULL,
s_id INT NOT NULL,
f_name char(255) NOT NULL,
f_price DECIMAL(8,2) NOT NULL,
PRIMARY KEY(f_id)
);

解釋:
f_id:主鍵 使用的是CHAR型別的字元來代表主鍵
s_id:這個其實是供應商的編號,也就是代表該水果是從哪個供應商那裡過來的,寫這個欄位的目的是為了方便後面擴增表。
f_name:水果的名字
f_price:水果的價格,使用的是DECIMAL這個資料型別

 

建立結果用desc命令檢視:

 

新增資料:

為了防止在cmd中直接敲打程式碼出錯,所以新建了InsertFruits.sql檔案,然後在cmd中呼叫:

//InsertFruits.sql

INSERT
INTO fruits(f_id,s_id,f_name,f_price) VALUES ('a1' , 101 , 'apple' , 5.2), ('b1' , 101 , 'blackberry' , 10.2), ('bs1' , 102 , 'orange' , 11.2), ('bs2' , 105 , 'melon' , 8.2), ('t1
' , 102 , 'banana' , 10.3), ('t2' , 102 , 'grape' , 5.3), ('o2' , 103 , 'coconut' , 9.2), ('c0' , 101 , 'cherry' , 3.2), ('a2' , 103 , 'apricot' , 2.2), ('l2' , 104 , 'lemon' , 6.4), ('b2' , 104 , 'berry' , 7.6), ('m1' , 106, 'mango' , 15.6), ('m2' , 105 , 'xbabay' , 2.6), ('t4' , 107, 'xbababa' , 3.6), ('m3' , 105
, 'xxtt' , 11.6), ('b5' , 107, 'xxxx' , 3.6 );

 1.1、查詢所有欄位

SELECT * FROM fruits;

* 代表所有欄位,也就是從表中將所有欄位下面的記錄度查詢出來

 

1.2、查詢指定欄位

SELECT f_name, f_price FROM fruits;

查詢f_name 和 f_price 欄位的記錄

 

1.3、查詢指定記錄(where關鍵字)

SELECT * FROM fruits WHERE f_name = 'apple';  //將名為apple的記錄的所有資訊度查詢出來

 

SELECT * FROM fruits WHERE f_price > 10;    //將價格大於10的記錄的所有欄位查詢出來

 

1.4、帶IN關鍵字的查詢

 SELECT * FROM fruits WHERE f_name IN('apple','orange');

 

SELECT * FROM fruits WHERE s_id NOT IN(101,105); //s_id 不為101或者105的記錄

 

IN和=的區別:

 

  • 相同點:均在WHERE中使用作為篩選條件之一、均是等於的含義
  •  不同點:IN可以規定多個值,=一次只能規定一個值,要規定多個值需要使用邏輯符號
select * from fruits where f_name in ('apple','orange');
可以轉換成 = 的表達:
select * from fruits where name='apple' or name='orange';

 

1.5、帶BETWEEN AND 的範圍查詢

SELECT * FROM fruits WHERE f_price BETWEEN 5 AND 15;  //f_price 在5到15之間,包括5和15。

 

1.6、帶LIKE的字元匹配查詢

LIKE: 相當於模糊查詢,和LIKE一起使用的萬用字元有  "%"、"_"  

                 "%":作用是能匹配任意長度的字元。

                 "_":只能匹配任意一個字元

SELECT * FROM fruits WHERE f_name LIKE 'c%';  //f_name以c字母開頭的所有記錄

 

SELECT * FROM fruits WHERE f_name LIKE 'c%y';  //f_name以b字母開頭,y字母結尾的所有記錄

 

SELECT * FROM fruits WHERE f_name LIKE '____y';   //此處有四個_,說明要查詢以y字母結尾並且y之前只有四

 

1.7、關鍵字DISTINCT(查詢結果不重複)

SELECT s_id FROM fruits;  //查詢所有的s_id,會出現很多重複的值。

 

SELECT DISTINCT s_id FROM fruits;//使用DISTINCT就能消除重複的值

 

1.8、對查詢結果排序(ORDER BY)

SELECT DISTINCT s_id FROM fruits ORDER BY s_id;    //預設就是升序,使用降序時用SELECT DISTINCT s_id FROM fruits ORDER BY s_id DESC;  

 

1.9 、分組查詢(GROUP BY)

不分組時查詢s_id,會出現一些重複的值

 

SELECT s_id FROM fruits GROUP BY s_id;  //將s_id進行分組,有實際意義,按s_id進行分組,從101批發商這裡拿的水果度會放在101這個組中

 

 

SELECT s_id, COUNT(f_name), GROUP_CONCAT(f_name) FROM fruits GROUP BY s_id; //
將s_id分組後,就沒有重複的值了,因為重複的度被分到一個組中去了,現在在來看看每個組中有多少個值

COUNT():作用是計算每個組中有多少條記錄, 

GROUP_CONCAT(): 將分組中的各個欄位的值顯示出來。concat本來是連線兩個或者多個字元,這裡GROUP_CONCAT(f_name)就是將這些水果名連線在一起

 

SELECT s_id, COUNT(f_name), GROUP_CONCAT(f_name), GROUP_CONCAT(f_price) FROM fruits GROUP BY s_id;  //這裡顯示多個列的連線

 

分組之後還可以進行條件過濾,將不想要的分組丟棄,使用關鍵字 HAVING

SELECT s_id,COUNT(f_name),GROUP_CONCAT(f_name) FROM fruits GROUP BY s_id HAVING COUNT(f_name) > 1;//他能夠過s_id分組,然後過濾出水果種類大於1的分組資訊。

總結:HAVING和WHERE都是進行條件過濾的,區別就在於 WHERE 是在分組之前進行過濾,而HAVING是在分組之後進行條件過濾。

 

 1.13、使用LIMIT限制查詢結果的數量

語法:
LIMIT[位置偏移量] 行數
SELECT * FROM fruits LIMIT 5,5; //從第5條資料開始,往後取5條資料,也就是從第6條到第10條

 

 

二、多表查詢

 搭建查詢環境,前面已經有一張表了,現在在增加一張suppliers(供應商)表和前面哪個fruits表建立練習,也就是說讓fruits中s_id欄位值指向suppliers的主鍵值,建立一個外來鍵約束關係。

CREATE TABLE suppliers(

s_id INT NOT NULL,
s_name CHAR(50) NOT NULL,
s_city CHAR(50) NULL,
s_zip CHAR(10) NULL,
s_call CHAR(50) NOT NULL,
PRIMARY KEY(s_id)
);   //在某個目錄下新建一個suppliers.sql的檔案

mysql> source C:\web\mysql-8.0.13\CommandCreateTables\suppliers.sql;// 建立一個suppliers新表  

 

INSERT INTO suppliers(s_id,s_name,s_city,s_zip,s_call)VALUES
(101,'Supplies A','Tianjin','400000','18075'),
(102,'Supplies B','Chongqing','400000','44333'),
(103,'Supplies C','Shanghai','400000','90046'),
(104,'Supplies D','Zhongshan','400000','11111'),
(105,'Supplies E','Taiyuang','400000','22222'),
(106,'Supplies F','Beijing','400000','45678'),
(107,'Supplies G','Zhengzhou','400000','33332');
mysql> source C:\web\mysql-8.0.13\CommandCreateTables\InsertSuppliers.sql   ;//插入資料

 

2.1、普通雙表連線查詢

問題:查詢水果的批發商編號(s_id),批發商名字(s_name),水果名稱(f_name),水果價格(f_price)。

分析:需要查詢兩張表。如果需要查詢兩張表,那麼兩張表的關係必定是外來鍵關係,或者類似於外來鍵關係(類似於也就是說兩張表並沒有真正加外來鍵約束,但是其特點和外來鍵是一樣的,就像上面我們手動建立的兩張表一樣,雖然沒有設定外來鍵關聯關係,但是其特性跟外來鍵關係是一樣的,都存在s_id欄位,這樣兩張表就聯絡起來了。)

SELECT s.s_id,s.s_name,f.f_name,f.f_price FROM fruits AS f, suppliers AS s WHERE f.s_id = s.s_id; //執行邏輯和順序:SELECT s.s_id,
      /s.s_name,f.f_name,f.f_price(選擇其中兩個表中的各兩個欄位,使用別名來進行訪問) 
      //FROM (fruits AS f取別名為了簡單好記), suppliers AS s(取別名) WHERE f.s_id = s.s_id;

附:
sql執行順序 (1)from   2) on (3) join (4) where (5)group by  (6) avg,sum....  (7)having (8) select (9) distinct (10) order by 

  也就是說,我們每次執行的SQL語句,都是從FROM開始的。

 

2.2、內連線查詢

格式:表名 INNER JOIN 表名 ON 連線條件

SELECT
s.s_id,s.s_name,f.f_name,f.f_price FROM fruits AS f INNER JOIN suppliers AS s ON f.s_id = s.s_id; //跟2.1的作用是一樣的

JOIN :基於兩個或多個表之間的共同欄位,把這些表符合條件的所有行結合起來,從而查詢到需要的資訊。

比如上述問題:查詢水果的供應商編號,供應商名字,水果名稱,水果價格

 

自連線查詢:涉及到的兩張表是同一張表。

問題:查詢供應f_id='a2'的水果供應商提供的其他水果種類?

SELECT f2.f_id,f2.f_name
FROM fruits AS f1 INNER JOIN fruits AS f2
ON f1.s_id = f2.s_id AND f1.f_id = 'a2';

 

 2.3、外連線查詢

2.3.1、左外連線查詢

不僅會顯示共有的,還會把table1的其他行也列出來(如圖綠色部分)。如果,右表沒有匹配的,則以NULL顯示。

 

 2.3.2、右外連線查詢

 

2.4 子查詢

帶ANY、SOME關鍵字的子查詢;

帶ALL關鍵字的子查詢;

帶EXISTS關鍵字的子查詢;

帶IN關鍵字的子查詢;

搭建環境
CREATE
TABLE tb11 (num1 INT NOT NULL); CREATE TABLE tb12 (num2 INT NOT NULL); INSERT INTO tb11 VALUES(1),(5),(13),(27); INSERT INTO tb12 VALUES(6),(14),(11),(20);
 ANY關鍵字接在一個比較操作符的後面,表示若與子查詢返回的任何值比較為TRUE,則返回TRUE,通俗點講,只要滿足任意一個條件,就返回TRUE。

SELECT num1 FROM tb11 WHERE num1 > ANY(SELECT num2 FROM tb12);//這裡就是將在tb12表中查詢的結果放在前一個查詢語句中充當條件引數。
//只要num1大於其結果中的任意一個數,那麼就算匹配。
//下圖解析:num2中的值為6,14,11,20;num1中13大於6,27大於num2中所有數,所以取出num1中的這兩個數

 

使用ALL時表示需要同時滿足所有條件。
SELECT num1 FROM tb11 WHERE num1 > ALL(SELECT num2 FROM tb12);  //num1需要大於所有的查詢結果才算匹配
SLEECT * FROM tb11 WHERE EXISTS(SELECT * FROM tb12 WHERE num2 = 3);  //查詢tb12中有沒有num2=3的記錄,有的話則會將tb11的所有記錄查詢出來,沒有的話,不做查詢
這個IN關鍵字的作用跟上面單表查詢的IN是一樣的,不過這裡IN中的引數放的是一個子查詢語句。
SELECT s_id,f_id,f_name
FROM fruits
WHERE s_id IN(SELECT s_id FROM suppliers WHERE s_id = 107);

具體例項類似,不贅述。