目錄
什么是SQL
SQL基本語法
排序-ORDER BY
選取不重復(fù)的數(shù)據(jù)-DISTINCT
WHERE子句
LIKE 操作符
邏輯操作符
計(jì)算字段Alias(別名)
匯總數(shù)據(jù)分組數(shù)據(jù)-GROUP
BY分組數(shù)據(jù)-HAVING
SELECT子句順序
子查詢
JOIN
UNION
CASE WHEN
CREATE TABLE
EXTRACT() 函數(shù)
SQL簡介
什么是數(shù)據(jù)庫(database)
保存有組織的數(shù)據(jù)的容器(通常是一個(gè)文件或一組文件)代承。
什么是SQL
SQL(發(fā)音為字母S-Q-L或sequel)是結(jié)構(gòu)化查詢語言(Structured Query Language)的縮寫喉磁。SQL用于訪問和處理數(shù)據(jù)庫的標(biāo)準(zhǔn)的計(jì)算機(jī)語言。
SQL語言分4類:
- 數(shù)據(jù)查詢語言(DQL):select田盈,from,where
- 數(shù)據(jù)操縱語言(DML):insert樟结,update瘤缩,delete
- 數(shù)據(jù)定義語言(DDL):create,alter檀轨,drop
- 數(shù)據(jù)控制語言(DCL):grant,revoke欺嗤,commit参萄,rollback,savepoint
基本語法
SQL的語法偏向自然語言煎饼,最簡單的形式如下
SELECT column1, column2....columnN
FROM table_name;
注意:SQL 不區(qū)分大小寫
假設(shè)有這樣的一張表products
prod_code | prod_name | prod_price | vend_id |
---|---|---|---|
p1001 | a | 10 | 1001 |
p1002 | b | 20 | 1002 |
p1003 | c | 30 | 1003 |
檢索單個(gè)列
SELECT prod_name
FROM products
檢索所有列
SELECT *
FROM products
從表中選取前10行
SELECT *
FROM products
LIMIT 10
SQL語法-子句
子句(clause) SQL語句由子句構(gòu)成讹挎,有些子句是必需的,而有的是可選的
一個(gè)子句通常由一個(gè)關(guān)鍵字和所提供的數(shù)據(jù)組成
子句的例子: SELECT
語句和 FROM
子句
排序-ORDER BY
ORDER BY
語句用于根據(jù)指定的列對結(jié)果集進(jìn)行排序吆玖。
ORDER BY
語句默認(rèn)按照升序?qū)τ涗涍M(jìn)行排序筒溃。
如果您希望按照降序?qū)τ涗涍M(jìn)行排序,可以使用 DESC
關(guān)鍵字沾乘。
SELECT *
FROM products
ORDER BY price
LIMIT 10
選取不重復(fù)的數(shù)據(jù)-DISTINCT
在表中怜奖,可能會(huì)包含重復(fù)值。這并不成問題翅阵,不過歪玲,有時(shí)您也許希望僅僅列出不同(distinct)的值。
關(guān)鍵詞 DISTINCT
用于返回唯一不同的值掷匠。
語法:
SELECT DISTINCT 列名稱 FROM 表名稱
SELECT DISTINCT prod_name
FROM products
WHERE子句
WHERE
作用:行級(jí)過濾
WHERE
子句的位置:在同時(shí)使用ORDER BY
和WHERE
子句時(shí)滥崩,應(yīng)該讓ORDER BY
位于WHERE
之后,否則會(huì)產(chǎn)生錯(cuò)誤
SELECT prod_price
FROM products
WHERE prod_price>=10;
常見的WHERE子句操作符
=
等于
<>
不等于
!=
不等于
<=
卸镉铩(等)于
>=
大(等)于
BETWEEN
兩者之間
SELECT prod_name,prod_price
FROM products
WHERE prod_price BETWEEN 5 AND 10;
注意:單引號(hào)用來限制字符串钙皮,如果將值與串類型的列進(jìn)行比較,則需要限定引號(hào)
SELECT prod_price
FROM products
WHERE prod_name='chengzi';
NULL
值(no value)
不包含值募强,它與字段包含0株灸、空字符串或僅僅包含空格不同
SELECT prod_name,prod_price
FROM products
WHERE prod_price IS NULL;
LIKE 操作符
有一個(gè)Persons
表:
Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Adams | John | Oxford Street | London |
2 | Bush | George | Fifth Avenue | New York |
3 | Carter | Thomas | Changan Street | Beijing |
例子 1
現(xiàn)在崇摄,我們希望從上面的 "Persons" 表中選取居住在以 "N" 開始的城市里的人:
我們可以使用下面的 SELECT 語句:
SELECT * FROM Persons
WHERE City LIKE 'N%'
提示:"%" 可用于定義通配符(模式中缺少的字母)擎值。
結(jié)果集:
Id | LastName | FirstName | Address | City |
---|---|---|---|---|
2 | Bush | George | Fifth Avenue | New York |
例子 2
接下來,我們希望從 "Persons" 表中選取居住在包含 "lon" 的城市里的人:
我們可以使用下面的 SELECT 語句:
SELECT * FROM Persons
WHERE City LIKE '%lon%’
結(jié)果集:
Id | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Adams | John | Oxford Street | London |
例子 3
通過使用 NOT
關(guān)鍵字逐抑,我們可以從 "Persons" 表中選取居住在不包含 "lon" 的城市里的人:
SELECT * FROM Persons
WHERE City NOT LIKE '%lon%'
結(jié)果集:
Id | LastName | FirstName | Address | City |
---|---|---|---|---|
2 | Bush | George | Fifth Avenue | New York |
3 | Carter | Thomas | Changan Street | Beijing |
邏輯操作符
操作符(operator)
用來聯(lián)結(jié)或改變WHERE子句中的子句的關(guān)鍵字鸠儿,也稱為邏輯操作符(logical operetor)
AND
操作符
SELECT prod_id,prod_price,prod_name
FROM products
WHERE vend_id=1003 and prod_price<=10;
OR
操作符
SELECT prod_id,prod_price,prod_name
FROM products
WHERE vend_id=1003 or vend_id=1004;
AND
在計(jì)算次序中優(yōu)先級(jí)較高,為避免操作符被錯(cuò)位組合,可以寫如下語句:
SELECT prod_id,prod_price,prod_name
FROM products
WHERE (vend_id=1003 or vend_id=1004) and prod_price>=10;
注意:圓括號(hào)比AND
和OR
優(yōu)先級(jí)更高
IN
操作符
SELECT prod_id,prod_price,prod_name
FROM products
WHERE vend_id IN (1002,1003)
ORDER BY prod_name;
NOT
操作符
SELECT prod_id,prod_price,prod_name
FROM products
WHERE vend_id NOT IN (1002,1003)
ORDER BY prod_name;
計(jì)算字段
字段(field)基本上與列(column)的意思相同
AS
(使用別名)
算術(shù)運(yùn)算:+-*/
加減乘除
SELECT prod_id,
quantity,
item_price,
quantity*item_price AS expanded_price
FROM orderitems
WHERE order_num = 20005
Alias(別名)
假設(shè)我們有兩個(gè)表分別是:"Persons" 和 "Product_Orders"进每。我們分別為它們指定別名 "p" 和 "po"汹粤。
現(xiàn)在,我們希望列出 "John Adams" 的所有定單田晚。
我們可以使用下面的 SELECT 語句:
SELECT po.OrderID, p.LastName, p.FirstName
FROM Persons AS p, Product_Orders AS po
WHERE p.LastName='Adams' AND p.FirstName='John'
不使用別名的 SELECT 語句:
SELECT Product_Orders.OrderID, Persons.LastName, Persons.FirstName
FROM Persons, Product_Orders
WHERE Persons.LastName='Adams' AND Persons.FirstName='John'
從上面兩條 SELECT 語句可以看到嘱兼,別名使查詢程序更易閱讀和書寫。
匯總數(shù)據(jù)
我們經(jīng)常需要匯總數(shù)據(jù)而不用把它們實(shí)際檢索出來
聚集函數(shù)(aggregate function) 運(yùn)行在行組上贤徒,計(jì)算和返回單個(gè)值的函數(shù)芹壕。
SELECT AVG(prod_price) AS avg_price
FROM products;
表:SQL聚集函數(shù)
函數(shù) | 說明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行數(shù) |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之和 |
分組數(shù)據(jù)-GROUP BY
分組允許把數(shù)據(jù)分為多個(gè)邏輯組,以便能對每個(gè)組進(jìn)行聚集計(jì)算接奈。
分組是在 SELECT 語句的 GROUP BY 子句中建立的
GROUP BY 子句可以包含任意數(shù)目的列
如果在 SELECT 中使用表達(dá)式踢涌,則必須在GROUP BY 子句中指定相同的表達(dá)式。不能使用別名序宦。
除聚集計(jì)算語句外睁壁, SELECT 語句中的每個(gè)列都必須在 GROUP BY 子句中給出。
GROUP BY 子句必須出現(xiàn)在 WHERE 子句之后互捌, ORDER BY 子句之前潘明。
SELECT vend_id,COUNT(*) AS num_prods
FROM products
GROUP BY vend_id;
輸出:
vend_id | num_prods |
---|---|
1001 | 3 |
1002 | 10 |
1003 | 7 |
分組數(shù)據(jù)--HAVING
HAVING 子句
HAVING 非常類似于 WHERE
目前為止所學(xué)過的所有類型的 WHERE 子句都可以用 HAVING 來替代
差別是WHERE 過濾行,而 HAVING 過濾分組
WHERE 在數(shù)據(jù)分組前進(jìn)行過濾疫剃, HAVING 在數(shù)據(jù)分組后進(jìn)行過濾
SELECT cust_id,COUNT(*) AS orders
FROM orders
GROUP BY cust_id
HAVING COUNT(*) >= 2;
輸出:
cust_id | orders |
---|---|
10001 | 3 |
SELECT子句順序
子句 | 說明 | 是否必須使用 |
---|---|---|
SELECT | 要返回的列或表達(dá)式 | 是 |
FROM | 從中檢索數(shù)據(jù)的表 | 僅在從表選擇數(shù)據(jù)時(shí)使用 |
WHERE | 行級(jí)過濾 | 否 |
GROUP BY | 分組說明 | 僅在按組計(jì)算聚集時(shí)使用 |
HAVING | 組級(jí)過濾 | 否 |
ORDER BY | 輸出排序順序 | 否 |
LIMIT | 要檢索的行數(shù) | 否 |
子查詢
可以把一條 SELECT語句返回的結(jié)果用于另一條 SELECT 語句的 WHERE 子句钉疫。
SELECT cust_id
FROM orders
WHERE order_num IN (SELECT order_num
FROM orderitems
WHERE prod_id = 'TNT2');
JOIN
作用: 用于根據(jù)兩個(gè)或多個(gè)表中的列之間的關(guān)系,從這些表中查詢數(shù)據(jù)巢价。
Join 和 Key
有時(shí)為了得到完整的結(jié)果牲阁,我們需要從兩個(gè)或更多的表中獲取結(jié)果。我們就需要執(zhí)行 join
壤躲。
數(shù)據(jù)庫中的表可通過鍵將彼此聯(lián)系起來城菊。主鍵(Primary Key
)是一個(gè)列(或多個(gè)列),在這個(gè)列中的每一行的值都是唯一的碉克。在表中凌唬,每個(gè)主鍵的值都是唯一的。這樣做的目的是在不重復(fù)每個(gè)表中的所有數(shù)據(jù)的情況下漏麦,把表間的數(shù)據(jù)交叉捆綁在一起客税。
請看 "Persons" 表:
Id_P | LastName | FirstName | Address | City |
---|---|---|---|---|
1 | Adams | John | Oxford Street | London |
2 | Bush | George | Fifth Avenue | New York |
3 | Carter | Thomas | Changan Street | Beijing |
請注意,"Id_P" 列是 Persons 表中的的主鍵撕贞。這意味著沒有兩行能夠擁有相同的 Id_P
更耻。即使兩個(gè)人的姓名完全相同,Id_P
也可以區(qū)分他們捏膨。
接下來請看 "Orders" 表:
Id_O | OrderNo | Id_P |
---|---|---|
1 | 77895 | 3 |
2 | 44678 | 3 |
3 | 22456 | 1 |
4 | 24562 | 1 |
5 | 34764 | 65 |
引用兩個(gè)表
我們可以通過引用兩個(gè)表的方式秧均,從兩個(gè)表中獲取數(shù)據(jù):
誰訂購了產(chǎn)品食侮,并且他們訂購了什么產(chǎn)品?
SELECT Persons.LastName, Persons.FirstName, Orders.OrderNo
FROM Persons
INNER JOIN Orders
ON Persons.Id_P = Orders.Id_P
ORDER BY Persons.LastName
結(jié)果集:
LastName | FirstName | OrderNo |
---|---|---|
Adams | John | 22456 |
Adams | John | 24562 |
Carter | Thomas | 77895 |
Carter | Thomas | 44678 |
不同的 SQL JOIN
除了我們在上面的例子中使用的 INNER JOIN(內(nèi)連接)目胡,我們還可以使用其他幾種連接锯七。
下面列出了您可以使用的 JOIN 類型,以及它們之間的差異誉己。
- JOIN: 如果表中有至少一個(gè)匹配眉尸,則返回行
- LEFT JOIN: 即使右表中沒有匹配,也從左表返回所有的行
- RIGHT JOIN: 即使左表中沒有匹配巨双,也從右表返回所有的行
- FULL JOIN: 只要其中一個(gè)表中存在匹配效五,就返回行
UNION
UNION 操作符用于合并兩個(gè)或多個(gè) SELECT 語句的結(jié)果集。
請注意炉峰,UNION 內(nèi)部的 SELECT 語句必須擁有相同數(shù)量的列畏妖。列也必須擁有相似的數(shù)據(jù)類型。同時(shí)疼阔,每條 SELECT 語句中的列的順序必須相同戒劫。
UNION
語法
SELECT column_name(s) FROM table_name1
UNION
SELECT column_name(s) FROM table_name2
注釋:默認(rèn)地,UNION 操作符選取不同的值婆廊。如果允許重復(fù)的值迅细,請使用 UNION ALL。
UNION ALL
語法
SELECT column_name(s) FROM table_name1
UNION ALL
SELECT column_name(s) FROM table_name2
另外淘邻,UNION 結(jié)果集中的列名總是等于 UNION 中第一個(gè) SELECT 語句中的列名茵典。
CASE WHEN
CASE
具有兩種格式。簡單CASE
函數(shù)和CASE
搜索函數(shù)宾舅。
簡單CASE
函數(shù)
CASE sex
WHEN '1' THEN '男'
WHEN '2' THEN '女'
ELSE '其他' END
CASE
搜索函數(shù)
CASE WHEN sex = '1' THEN '男'
WHEN sex = '2' THEN '女'
ELSE '其他' END
已知數(shù)據(jù)按照另外一種方式進(jìn)行分組
有如下的表:
country | population |
---|---|
中國 | 600 |
美國 | 100 |
加拿大 | 100 |
英國 | 200 |
法國 | 300 |
日本 | 250 |
德國 | 200 |
墨西哥 | 50 |
印度 | 250 |
根據(jù)這個(gè)國家人口數(shù)據(jù)统阿,統(tǒng)計(jì)亞洲和北美洲的人口數(shù)量
SELECT CASE country
WHEN '中國' THEN '亞洲'
WHEN '印度' THEN '亞洲'
WHEN '日本' THEN '亞洲'
WHEN '美國' THEN '北美洲'
WHEN '加拿大' THEN '北美洲'
WHEN '墨西哥' THEN '北美洲'
ELSE '其他' END AS 洲
,SUM(population) AS 人口
FROM Table_A
GROUP BY CASE country
WHEN '中國' THEN '亞洲'
WHEN '印度' THEN '亞洲'
WHEN '日本' THEN '亞洲'
WHEN '美國' THEN '北美洲'
WHEN '加拿大' THEN '北美洲'
WHEN '墨西哥' THEN '北美洲'
ELSE '其他' END;
輸出:
洲 | 人口 |
---|---|
亞洲 | 1100 |
北美洲 | 250 |
其他 | 700 |
實(shí)現(xiàn)類似數(shù)據(jù)透視表的功能
有如下數(shù)據(jù)
country | sex | population |
---|---|---|
中國 | 1 | 340 |
中國 | 2 | 260 |
美國 | 1 | 45 |
美國 | 2 | 55 |
加拿大 | 1 | 51 |
加拿大 | 2 | 49 |
英國 | 1 | 40 |
英國 | 2 | 60 |
按照國家和性別進(jìn)行分組筹我,得出結(jié)果如下
國家 | 男 | 女 |
---|---|---|
中國 | 340 | 260 |
美國 | 45 | 55 |
加拿大 | 51 | 49 |
英國 | 40 | 60 |
SELECT country,
SUM( CASE WHEN sex = '1' THEN
population ELSE 0 END) AS 男, --男性人口
SUM( CASE WHEN sex = '2' THEN
population ELSE 0 END) AS 女--女性人口
FROM Table_A
GROUP BY country;
CREATE TABLE
創(chuàng)建空表
如要?jiǎng)?chuàng)建一個(gè)列名分別是"Id_P"扶平、"LastName"、"FirstName"蔬蕊、"Address" 以及 "City"的空表结澄,表名為Persons
:
CREATE TABLE Persons
(
Id_P int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)
SELECT的結(jié)果集來創(chuàng)建表
create table person_table
as
select id,name from person;
EXTRACT() 函數(shù)
定義和用法
EXTRACT()
函數(shù)用于返回日期/時(shí)間的單獨(dú)部分,比如年岸夯、月麻献、日、小時(shí)猜扮、分鐘等等勉吻。
語法
EXTRACT(unit FROM date)
假設(shè)我們有如下的表:
OrderId | ProductName | OrderDate |
---|---|---|
1 | 'Computer' | 2008-12-29 16:25:46.635 |
我們使用下面的 SELECT 語句:
SELECT EXTRACT(YEAR FROM OrderDate) AS OrderYear,
EXTRACT(MONTH FROM OrderDate) AS OrderMonth,
EXTRACT(DAY FROM OrderDate) AS OrderDay
FROM Orders
WHERE OrderId=1
完