天天看點

My SQL-DW組隊學習2️⃣

目錄

SELECT語句基礎

SELECT語句

WHERE語句

算術運算符和比較運算符

算術運算符

比較運算符

常用法則

邏輯運算符

NOT運算符

AND運算符和OR運算符

真值表

含有NULL時的真值

對表進行聚合查詢

聚合函數

使用聚合函數删除重複值

常用法則

對表進行分組

GROUP BY語句

聚合鍵中包含NULL時

GROUP BY書寫位置

為聚合結果指定條件

用HAVING得到特定分組

HAVING特點

對查詢結果進行排序

ORDER BY

ORDER BY中列名可使用别名

作業

SELECT語句基礎

SELECT語句

從表中選取資料時需要使用SELECT語句,也就是隻從表中選出(SELECT)必要資料的意思。通過SELECT語句查詢并選取出必要資料的過程稱為比對查詢或查詢(query)。

基本SELECT語句包含了SELECT和FROM兩個子句(clause)。示例如下:

SELECT <列名>, 
  FROM <表名>;
           

其中,SELECT子句中列舉了希望從表中查詢出的列的名稱,而FROM子句則指定了選取出資料的表的名稱。

WHERE語句

當不需要取出全部資料,而是選取出滿足某些條件的資料時,使用WHERE語句。

SELECT 語句通過WHERE子句來指定查詢資料的條件。在WHERE 子句中可以指定“某一列的值和這個字元串相等”或者“某一列的值大于這個數字”等條件。執行含有這些條件的SELECT語句,就可以查詢出隻符合該條件的記錄了。

SELECT <列名>, ……
  FROM <表名>
 WHERE <條件表達式>;
           
-- 想要查詢出全部列時,可以使用代表所有列的星号(*)。
SELECT *
  FROM <表名>;
-- SQL語句可以使用AS關鍵字為列設定别名(用中文時需要雙引号(“”))。
SELECT product_id     AS id,
       product_name   AS name,
       purchase_price AS "進貨單價"
  FROM product;
-- 使用DISTINCT删除product_type列中重複的資料
SELECT DISTINCT product_type
  FROM product;
           
  • 星号(*)代表全部列的意思。
  • SQL中可以随意使用換行符,不影響語句執行(但不可插入空行)。
  • 設定漢語别名時需要使用雙引号(")括起來。
  • 在SELECT語句中使用DISTINCT可以删除重複行。
  • SQL中注釋分為1行注釋"-- "和多行注釋""兩種。
  • AS 後接所選列的昵稱。

算術運算符和比較運算符

算術運算符

SQL語句中可以使用的四則運算的主要運算符如下:

含義 運算符
加法 +
減法 -
乘法 *
除法 /

比較運算符

SQL常見比較運算符如下:

運算符 含義
= 和~相等
<> 和~不相等
>= 大于等于~
> 大于~
<= 小于等于~
< 小于~

常用法則

  • SELECT子句中可以使用常數或者表達式。
  • 使用比較運算符時一定要注意不等号和等号的位置。
  • 字元串類型的資料原則上按照字典順序進行排序,不能與數字的大小順序混淆。
  • 希望選取NULL記錄時,需要在條件表達式中使用IS NULL運算符。希望選取不是NULL的記錄時,需要在條件表達式中使用IS NOT NULL運算符。

相關代碼如下:

/* 對字元串使用不等号
首先建立chars并插入資料
選取出大于‘2’的SELECT語句*/
-- DDL:建立表
CREATE TABLE chars
(chr CHAR(3)NOT NULL,
PRIMARY KEY(chr));
-- 選取出大于'2'的資料的SELECT語句('2'為字元串)
SELECT chr
  FROM chars
 WHERE chr > '2';
-- 選取NULL的記錄
SELECT product_name, purchase_price
  FROM product
 WHERE purchase_price IS NULL;
-- 選取不為NULL的記錄
SELECT product_name, purchase_price
  FROM product
 WHERE purchase_price IS NOT NULL;
           

邏輯運算符

NOT運算符

想要表示“不是……”時,除了前文的<>運算符外,還存在另外一個表示否定、使用範圍更廣的運算符:NOT。

NOT不能單獨使用。

-- 選取出銷售單價大于等于1000日元的記錄
SELECT product_name, product_type, sale_price
  FROM product
 WHERE sale_price >= 1000;
-- 向代碼清單2-30的查詢條件中添加NOT運算符
SELECT product_name, product_type, sale_price
  FROM product
 WHERE NOT sale_price >= 1000;
           

AND運算符和OR運算符

當希望同時使用多個查詢條件時,可以使用AND或者OR運算符。

AND 相當于“并且”,類似數學中的取交集;

OR 相當于“或者”,類似數學中的取并集。

AND運算符工作效果圖:

My SQL-DW組隊學習2️⃣

OR運算符工作效果圖:

My SQL-DW組隊學習2️⃣
-- 将查詢條件原封不動地寫入條件表達式,會得到錯誤結果
SELECT product_name, product_type, regist_date
  FROM product
 WHERE product_type = '辦公用品'
   AND regist_date = '2009-09-11'
    OR regist_date = '2009-09-20';
           

錯誤的原因是是 AND 運算符優先于 OR 運算符,想要優先執行OR運算,可以使用括号:

-- 通過使用括号讓OR運算符先于AND運算符執行
SELECT product_name, product_type, regist_date
  FROM product
 WHERE product_type = '辦公用品'
   AND ( regist_date = '2009-09-11'
        OR regist_date = '2009-09-20');
           

真值表

本節介紹的三個運算符 NOT、AND 和 OR 稱為邏輯運算符。這裡所說的邏輯就是對真值進行操作的意思。真值就是值為真(TRUE)或假 (FALSE)其中之一的值。

AND 運算符兩側的真值都為真時傳回真,除此之外都傳回假。

OR 運算符兩側的真值隻要有一個不為假就傳回真,隻有當其兩側的真值都為假時才傳回假。

NOT運算符隻是單純的将真轉換為假,将假轉換為真。

My SQL-DW組隊學習2️⃣

查詢條件為P AND(Q OR R)的真值表

My SQL-DW組隊學習2️⃣

含有NULL時的真值

NULL的真值結果既不為真,也不為假,因為并不知道這樣一個值。

這時真值是除真假之外的第三種值——不确定(UNKNOWN)。一般的邏輯運算并不存在這第三種值。SQL 之外的語言也基本上隻使用真和假這兩種真值。與通常的邏輯運算被稱為二值邏輯相對,隻有 SQL 中的邏輯運算被稱為三值邏輯。

三值邏輯下的AND和OR真值表為:

My SQL-DW組隊學習2️⃣

對表進行聚合查詢

聚合函數

SQL中用于彙總的函數叫做聚合函數。以下五個是最常用的聚合函數:

  • COUNT:計算表中的記錄數(行數)
  • SUM:計算表中數值列中資料的合計值
  • AVG:計算表中數值列中資料的平均值
  • MAX:求出表中任意列中資料的最大值
  • MIN:求出表中任意列中資料的最小值
-- 計算全部資料的行數(包含NULL)
SELECT COUNT(*)
  FROM product;
-- 計算NULL以外資料的行數
SELECT COUNT(purchase_price)
  FROM product;
-- 計算銷售單價和進貨單價的合計值
SELECT SUM(sale_price), SUM(purchase_price) 
  FROM product;
-- 計算銷售單價和進貨單價的平均值
SELECT AVG(sale_price), AVG(purchase_price)
  FROM product;
-- MAX和MIN也可用于非數值型資料
SELECT MAX(regist_date), MIN(regist_date)
  FROM product;
           

使用聚合函數删除重複值

-- 計算去除重複資料後的資料行數
SELECT COUNT(DISTINCT product_type)
 FROM product;
-- 是否使用DISTINCT時的動作差異(SUM函數)
SELECT SUM(sale_price), SUM(DISTINCT sale_price)
 FROM product;
           

常用法則

  • COUNT函數的結果根據參數的不同而不同。COUNT(*)會得到包含NULL的資料行數,而COUNT(<列名>)會得到NULL之外的資料行數。
  • 聚合函數會将NULL排除在外。但COUNT(*)例外,并不會排除NULL。
  • MAX/MIN函數幾乎适用于所有資料類型的列。SUM/AVG函數隻适用于數值類型的列。
  • 想要計算值的種類時,可以在COUNT函數的參數中使用DISTINCT。
  • 在聚合函數的參數中使用DISTINCT,可以删除重複資料。

對表進行分組

GROUP BY語句

之前使用聚合函數都是會整個表的資料進行處理,當你想将進行分組彙總時(即:将現有的資料按照某列來彙總統計),GROUP BY可以幫助你:

SELECT <列名1>,<列名2>, <列名3>, ……
  FROM <表名>
 GROUP BY <列名1>, <列名2>, <列名3>, ……;
           

是否使用GROUP BY語句的差異:

-- 按照商品種類統計資料行數,傳回多行
SELECT product_type, COUNT(*)
  FROM product
 GROUP BY product_type;
 -- 不含GROUP BY,傳回一行
SELECT product_type, COUNT(*)
  FROM product;
           

對比查詢結果可以看到,使用 

GROUP BY

 子句的查詢傳回多行,而不使用 GROUP BY 的查詢則僅傳回一行。

GROUP BY 子句就像切蛋糕那樣将表進行了分組。

在 GROUP BY 子句中指定的列稱為聚合鍵或者分組列。

聚合鍵中包含NULL時

此時會将NULL作為一組特殊資料進行處理。

GROUP BY書寫位置

GROUP BY的子句書寫順序有嚴格要求,不按要求會導緻SQL無法正常執行,目前出現過的子句書寫順序為:

1. SELECT → 2. FROM → 3. WHERE → 4. GROUP BY

其中前三項用于篩選資料,GROUP BY對篩選出的資料進行處理。

為聚合結果指定條件

用HAVING得到特定分組

将表使用GROUP BY分組後,怎樣才能隻取出其中兩組?

這裡WHERE不可行,因為,WHERE子句隻能指定記錄(行)的條件,而不能用來指定組的條件

可以在GROUP BY後使用HAVING子句,HAVING的用法類似WHERE。

HAVING特點

HAVING子句用于對分組進行過濾,可以使用數字、聚合函數和GROUP BY中指定的列名(聚合鍵)。

-- 數字 找出分組行數為2的小組
SELECT product_type, COUNT(*)
  FROM product
 GROUP BY product_type
HAVING COUNT(*) = 2;
-- 錯誤形式(因為product_name不包含在GROUP BY聚合鍵中)
SELECT product_type, COUNT(*)
  FROM product
 GROUP BY product_type
HAVING product_name = '原子筆';
           

對查詢結果進行排序

ORDER BY

SQL中的執行結果是随機排列的,當需要按照特定順序排序時,可已使用ORDER BY子句。

SELECT <列名1>, <列名2>, <列名3>, ……
  FROM <表名>
 ORDER BY <排序基準列1>, <排序基準列2>, ……
           

預設為升序排列,降序排列為DESC

-- 降序排列
SELECT product_id, product_name, sale_price, purchase_price
  FROM product
 ORDER BY sale_price DESC;
-- 多個排序鍵
SELECT product_id, product_name, sale_price, purchase_price
  FROM product
 ORDER BY sale_price, product_id;
-- 當用于排序的列名中含有NULL時,NULL會在開頭或末尾進行彙總。
SELECT product_id, product_name, sale_price, purchase_price
  FROM product
 ORDER BY purchase_price;
           

ORDER BY中列名可使用别名

SQL在使用 HAVING 子句時 SELECT 語句的執行順序為:

FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY

其中SELECT的執行順序在 GROUP BY 子句之後,ORDER BY 子句之前。也就是說,當在ORDER BY中使用别名時,已經知道了SELECT設定的别名存在,但是在GROUP BY中使用别名時還不知道别名的存在,是以 在ORDER BY中可以使用别名,但是在GROUP BY中不能使用别名。

作業

SELECT product_name,regist_date
	FROM product
	WHERE regist_date > '2009-04-28';

--
-- 
-- 

SELECT product_name,sale_price,purchase_price
	FROM product
	WHERE sale_price - purchase_price =500
	OR sale_price - purchase_price =1200
	OR sale_price - purchase_price =1800;
    
select product_name,product_type, sale_price*0.9 - purchase_price as profit
from product
where sale_price*0.9 - purchase_price > 100
and (product_type="辦公用品"
or product_type="廚房用品");
    
-- SUM後非數值而是字元串
-- GROUP BY書寫順序應該在WHERE之後

select product_type,sum(sale_price),sum(purchase_price)
from product
group by product_type
having sum(sale_price) > sum(purchase_price)*1.5;

null位置具體情況具體分析,有時候需要進行特殊處理。