1. 程式人生 > >《SQL必知必會》閱讀筆記

《SQL必知必會》閱讀筆記

【自言自語】對於資料庫sql語言,之前都是用的時候再查,沒有系統的瞭解,用了一天半把這個書看完了,所以需要總結一下,不過,我沒有寫遊標、儲存過程這些,因為我覺得書中講的過淺了。等下一本書看完,或許有更好的理解。到時候,再寫關於那幾個方面的我覺得是不錯的。這段時間抓緊時間啃書啊,書越借越多。

SQL和Java、C不一樣,他只有很少的詞。他不是某個特定資料庫提供商專有的語言。幾乎所有重要的DBMS都支援SQL,但是有些細節地方還是要去看該DBMS的詳細文件。

資料庫增刪改查操作

一、建立資料庫

CREATE DATABASE test;

二、檢視資料庫

  1. SHOW DATABASES;
  2. 檢視當前資料庫
    • SELECT DATABASE();
      直接可以看出資料庫名稱
    • SHOW TABLES;檢視所有表操作也可以顯示出資料庫名稱

三、切換指定資料庫

USE test;

四、建立表

CREATE TABLE client( ​ id INT, ​ age INT, ​ name VARCHAR(20), ​ gender VARCHAR(1) );

五、查看錶資料

DESC client;

六、增刪改查

1. 增

  • INSERT INTO client VALUES(1,20,'zhangsan','female'); 插入所有欄位
  • INSERT INTO client(id,name) VALUES(2,'zhansgan'); 插入部分欄位
    • 省略的列需要被定義為允許NULL
      值(無值或空值)
    • 在表中給出預設值。表示如果不給出值,將使用預設值。
  • INSERT INTO client(id,name) SELECT id,name from oldClient;
    • 插入檢索出的語句,它可以用一條INSERT插入多行,不管SELECT返回多少行,都將被INSERT插入。
  • Create TABLE CustCopy AS SELECT * from Customers;
    • 建立一個新表,將Customers表的整體內容複製到新表中。

2. 改

  • UPDATE client SET gender='female'; 修改所有資料(使用較少),修改範圍較大。
  • UPDATE client SET gender='mael' WHERE id=1;
    修改部分資料(使用較多),修改範圍較小
  • UPDATE client SET gender='male' , age=30 WHERE id=2;修改多個欄位,中間用英文逗號分隔。

3. 刪

  • DELETE FROM client;刪除該表的所有資料,可以帶條件刪除。
    • 若執行該指令,只會刪除table的所有資料,但是不能刪除表的約束。例如自增長的繼續增長。
    • 使用該指令,刪除的資料可以回滾。
  • DELETE FROM client WHERE id=2;刪除帶條件的資料。
  • TRUNCATE TABLE client;全表刪除,不能帶條件刪除。

4. 查詢資料(基於一張表)

查詢出來的順序未必是按照 存放的順序。

4.1 查詢所有列

SELECT * FROM client查詢所有列 *代表所有 ``

4.2 查詢制定列

SELECT id,name,FROM client; SELECT id, AS '編號',name AS '姓名' FROM client AS 's';查詢時指定別名(as),再多表查詢時,經常使用!

4.3 查詢時新增常量列

SELECT id,name ,'常量列' AS ‘常數列的表頭’ FROM cilent;

4.4 查詢是合併列

SELECT id,name (a2+a3) AS '新專案' FROM client;只能合併數值型別

4.5 查詢時去除重複記錄

SELECT DISTINCT gender FROM client; SELECT DISTINCT(gender) FROM client;

**PS:**不能部分使用DISTINCT:

  • 該關鍵字作用於所有的列,不僅僅是跟在其後的那一列。
  • 例如你指定select distinct id,name,除非指定的兩列完全相同,否則所有的行都會被檢索出來。
4.6 條件查詢
  • 邏輯條件 and or SELECT * FROM client WHERE id=2 AND name='zhangsan';兩個欄位以上的之間一定會有邏輯關係!

  • 比較條件 > 、<、 >=、 <=、 ==、 <>或!=(不等於) between and SELECT * FROM client WHERE 指定項>=70 AND 指定項2<=90; SELECT * FROM client WHERE 制定項 BETWEEN 70 AND 95 SELECT * FROM client WHERE gender <> 'male';尋找性別不為男的資料。

    SELECT * FROM client WHERE age in (16,18)

    • IN:Where子句中用來指定要匹配值的清單的關鍵字,功能和OR相當。
    • IN操作符一般比一組OR操作符執行的更快。
  • 判空(null / 空字串) is null /is not null NULL :沒有值 空字串 :有值。 SELECT * FROM client WHERE address IS NULL ;判斷NULL SELECT * FROM client WHERE address='';判斷空字串 SELECT * FROM client WHERE address IS NULL OR address='';包括NULL和空字串。

    SELECT * FROM client WHERE address IS NOT NULL AND address<>'';

  • 模糊查詢

    只適用於字串型別。

    通常使用以下替換標記

    • %:表示任意字元出現任意次數(可以是0次)
    • _:(下劃線)表示一個字元。
    • []:指定一個字符集,
    • SELECT * FROM client WHERE name LIKE 'zhang%'; SELECT * FROM client WHERE name LIKE 'zhang_' ;
4.7 聚集函式

常用的聚集函式:sum() avg() max() min() count()

這些函式都很高效,它們返回的結果一般比你在自己的客戶端應用程式中計算要快得多。

  • AVG()返回某列的平均值
    • select avg(prod_price) AS avg_price from products;
    • 該函式忽略列值為NULL的行。
  • COUNT()返回某列的行數
    • 使用count(*)對錶中的行數目進行計數。(不忽略NULL值)
    • 使用count(列名)同樣也是對錶中該列的行數目進行計數。(忽略NULL值)
  • MAX()返回某列的最大值
    • 用於文字資料時,MAX()返回該列排序後的最後一行。
    • 忽略值為NULL的行
  • MIN()返回某列的最小值
    • 用於文字資料時,MAX()返回該列排序後的最前面的行。
    • 忽略值為NULL的行
  • SUM()返回某列值之和
    • 忽略值為NULL的行
    • select sum(item_price*quantity) AS total_price from OrderItems where order_num = 20005;
4.8 分頁查詢 (limit 起始行,查詢幾行)

起始行從0開始 select * from client limit 0,2;

4.9 查詢排序(order by
4.9.1 按多個列排序

select prod_id,prod_price,prod_name from products order by prod_price,prod_name; 先按照 prod_price進行排序,然後按照prod_name進行排序。

4.9.2 按列位置排序

select prod_id,prod_price,prod_name from products order by 2,3; select清單中指定的是列的相對位置而不是列名。 order by 2.3表示先按prod_price排序,再按照prod_name進行排序。

4.9.3 指定排序方向

**PS:**如果想在多個列上進行降序排序,必須對每一列指定DESC關鍵字。 asc:順序,反序。數值:遞增,字母:自然順序。 desc:反序。

4.11分組查詢(group by)

分組篩選後查詢

七. 資料處理

1. 建立計算欄位
  • 拼接欄位(例如:拼接兩個字串)
    • select province + '('+county+')' AS userAddress from address order by county;
  • 執行算術計算
    • select id,count,price,count*price AS money from OrderItems;
    • 算術操作符有四種。+-*/
2. 使用函式處理資料

​ 由於每個DBMS都有自己的特性,所以這裡就不列出每個DBMS的函式。只舉例說明如何運用。

2.1 文字處理函式
  • UPPER()將文字轉換成大寫。
    • select vend_name,UPPER(vend_name) AS vend_name_upcase from vendors order by vend_name
  • RTRIM()去掉字串右邊的空格。
  • LTRIM()去掉字串左邊的空格。
  • TRIM()去掉字串中的空格。
2.2數值處理函式
  • abs()返回一個數的絕對值
  • cos()返回一個角度的餘弦
  • exp()返回一個數的指數值
  • PI()返回圓周率
2.3 日期處理函式
  • Year()返回日期的年份。(Mysql)
3 分組資料
3.1 建立分組

select vend_id,count(*) as num_prods from products group by vend_id;

  • Group By子句可以包含任意數目的列,因而可以對分組進行巢狀。
  • Group By子句必須出現在Where子句之後,Order By子句之前。1
3.2 過濾分組

select vend_id,count(*) AS orders from Orders Group By cust_id HAVING count(*) >=2

Having來過濾分組,上一句SQL語句的意思是 對小於兩個訂單的分組進行過濾。

wherehaving的區別:

  • 前者是在資料分組前進行過濾,後者實在資料分組後進行過濾。
  • where排除的行不在這些分組中。
  • 使用HAVING時應該結合GROUP BY子句,而WHERE子句用於標準的行級過濾。
3.3 分組和排序

Group byORDER BY經常完成相同的工作,但他們非常不同。

  • 前者對行進行分組,但輸出可能不是分組的順序;後者對產生的輸出排序。
  • 一般在使用GROUP BY 子句時,應該也給出ORDER BY子句,這是保證資料正確排序的唯一方法。

select order_num , count(*) AS items from orderItems group by oredr_num having count(*) >=3 order by items,oredr_num;

3.4 SELECT 子句的順序

select(必) .....from.....where ....group by .... having .....order by

4. 子查詢

sql中允許子查詢,即巢狀在其他查詢中的查詢。

在SELECT語句中,子查詢總是從內向外處理。

select cust_id from orders where order_num IN (
	select order_num from orderItems where prod_id = 'RGAN01');

在實際的DBMS中,實際上執行了兩個操作。

再比如:

select cust_name,cust_contact from customers where cust_id IN(
	select cust_id from Orders where order_num IN(
    	select order_num from OrderItems where prod_id = '45274'
    )
);

上述sql程式碼執行了三個 select子語句。

對於能巢狀的子查詢的數目沒有限制,不過在實際使用時由於效能的限制,不能巢狀太多的子查詢。

PS:

  • 作為子查詢的select語句能查詢單個列
  • 使用子查詢並不總是執行這類資料檢索的最有效的方法。
select cust_name,cust_state,(
	select count(*) from orders where orders.cust_id = Customers.cust_id) As orderNUM
) from customers order by cust_name;

order是一個計算欄位,她是由圓括號中的子查詢建立的。該子查詢對檢索出的每個顧客執行一次。

cuwstomers.cust_id.是全限定列名。

5. 聯結表

關於什麼 是聯結,請上百度搜索,百度比我講的清楚。我只簡單的點一下。

資料儲存在多個表中,有些業務需要將他們聯絡起來,檢索出來。

聯結是一種機制,用來在一條SELECT語句中關聯表,因此稱為聯結

使用特殊的語法,可以聯結多個表返回一組輸出。

5.1 建立聯結

簡單寫法:

select vend_name,prod_name,prod_price from vendors,Products where 
	vendors.vend_id = Products.vend_id;

**PS:**在引用的列名會產生歧義時,必須使用完全限定列名。

上邊使用的聯結方式稱為等值聯結,它基於兩個表之間的相等測試,這種聯結也成為內聯結

另外一種標準寫法:

select vend_name,prod_name,prod_price from vendors INNER JOIN Products
	on vendors.vend_id = Products.vend_id;

兩個表之間的關係是以INNER JOIN指定的部分FROM子句。在使用這種語法時,聯結條件用特定的ON子句而不是WHERE

至於選用哪種方法就需要看具體的DBMS文件。

5.2 聯結多個表
select prod_name,vend_name,prod_price,quantity from OrderItems,Products,Vendors Where
	Products.vend_id = Vendors.vend_id
And OrderItems.prod_id = Products.prod_id
And order_num = 20007;

不要聯結不必要的表,聯結的表越多,效能下降的越厲害。

6 建立高階聯結
6.1 使用表別名
  • 使用表別名 from 表名 AS 別名

    表別名只在查詢執行中使用,與列別名不一樣,表別名不返回到客戶端。

6.2 使用不同型別的聯結
  • 自聯結

    通常作為外部語句喲個來替代從相同表中檢索資料的子查詢語句。雖然結果相同,但是使用聯結要比使用子查詢效率高很多。

    • 使用子查詢:select id, name,address from user where address = (select address from user where age = 15);
    • 使用自聯結:select c1.name from user as c1,user as c2 where c1.address = c2.address and c2.age = 15;
  • 自然聯結

    • 實際上,我們建立的每個內聯結都是自然聯結。
  • 外聯結

    有兩種外聯結形式,它們之間的唯一差別是所關聯的表的順序。

    • 左外聯結LEFT OUTER JOIN 包含其所有行的表在左邊
    • 右外聯結RIGHT OUTER JOIN包含其所有行的表在右邊

八、使用檢視

1. 檢視是什麼?

檢視是虛擬的表。與包含資料的表不一樣,檢視只包含使用時動態檢索資料的查詢。

他不包含任何列和資料,包含的只是一個查詢。

2. 檢視有什麼作用?

  • 簡化複雜的SQL操作。在編寫查詢業務時,直接重用,不需要知道實現的細節。
  • 保護資料(可以授權使用者訪問表的特定部分的許可權,而不是整個表的訪問許可權)
  • 更改資料格式和表示。

3. 如何建立檢視?

那先說一下 檢視的規則和限制。(詳細的還是要根據所使用的DBMS來決定)

  • 與表一樣,檢視必須唯一命名。
  • 建立檢視,必須有足夠的訪問許可權

建立檢視:

CREATE VIEW ProductCustomers AS Select cust_name,cust_contact,prod_id from customers,Orders,OrderItems where customers.cust_id = Orders.cust_id and OrderItems.order_num = Orders.order_num;

這個 叫ProductCustomers的檢視,他聯結了三個表,返回已訂購了任意產品的所有顧客的列表。

比如,我們檢索訂購了產品id為0001紀梵希的顧客。

select cust_name,cust_contact from ProductCustomers where prod_id = '0001';

實際執行上邊的sql語句,檢視中的select會先執行。

用檢視重更新格式化檢索出的資料

create view viewTest AS select RTRIM(province) + '('+RTRIM(county)+')' AS address from User;

該試圖將使用者的省份和國籍進行格式化輸出。

End

SQL基本的會用之後,學習原理就相對來說簡單,更有針對性。