SQL:Structured Query Language,結構化查詢語言,是一種專門用來與數據庫通訊的語言,幾乎全部的DBMS(數據庫管理系統)都支持SQL,不是某種數據庫的專用語言mysql
MySQL:基於客戶機-服務器的DBMS。MySQL是服務器軟件,能夠在本地安裝的副本上運行,也能夠鏈接到具備訪問權限的遠程服務器上的副本。客戶機爲程序開發語言git
select distinct type from osc_users; /*返回惟一值的type行*/ select * from osc_opt_logs limit 6,5; /*從第6行開始返回5行*/
排序檢索數據正則表達式
select * from osc_users order by type;/*根據type值返回檢索數據*/ select id, type, activate_code from osc_users order by type,activate_code;/*根據type排序,當type相同時,根據activate_code排序木,默認爲升序排序*/ select id, type, activate_code from osc_users order by type desc ,activate_code desc ;/*desc表示降序排序,大小寫排序取決於數據庫如何設置*/ select * from osc_users order by type limit 1;/*limit必須在order by以後*/
select字句順序 where, order by, limitsql
本章講授如何使用select語句的where子句指定搜索條件數據庫
where字句操做符說明服務器
= 等於 <> 不等於 != 不等於 < 小於 <= 小於等於 > 大於 >= 大於等於 BETWEEN 在指定的兩個值之間
比較字符串時要使用單引號,比較值時不須要ide
select * from osc_users where id between 12 and 28;/*檢索id從12到28*/
空值檢查函數
select * from osc_users where ident is null;/*檢索ident爲null的user*/
AND 與,計算優先次序較OR高,可經過使用圓括號改變計算次序性能
OR 或spa
select * from osc_last_msgs where (user=12 or user=28) and sender=1;
IN 指定條件範圍
select * from osc_last_msgs where user in (12,28) and sender=1;
NOT 否認它以後所跟的任何條件
通配符(wildcard):用來匹配值的一部分的特殊字符
搜索模式(search pattern):由字面值、通配符或二者組合構成的搜索條件
% 通配符,表示任意長度的字符,可插入在字符串的任意位置
select * from osc_users where email like '%cn';
_ 通配符,表示任意單個字符
select * from osc_users where email like '_@os%';
注意:
1. 通配符搜索消耗時間長,能用其它方式搜索就不用通配符搜索
2. 通配符用在搜索模式的開始處搜索起來是最慢的,除非有必要,不然不要這樣使用
mysql只支持部分正則表達式
REGEXP 表示後面跟的正則表達式
select * from osc_users where email regexp 'oschina\\.cn';/*匹配包含oschina.cn的值*/ select * from osc_users where email like 'oschina.cn';/*這句無數據返回,like匹配的是整個列值,這是like關鍵字與regexp的重要區別*/
BINARY 在字符串前面使用,表示區分大小寫
| 或
select * from osc_users where email regexp 'oschina\\.cn|com' order by email desc;
匹配幾個字符之一 [abc] [a-z] [0-9]
匹配特殊字符,在字符前加上\\ 例如要匹配. 則使用\\.
匹配字符類
[:alnum:] 任意字母和數字 [:alpha:] 任意字符 [:blank:] 空格和製表 [:cntrl:] ASCII控制字符 [:lower:] 任意小寫字符 [:upper:] 任意大寫字符 [:digit:] 任意數字 [:xdigit:] 任意十六進制數字 [:space:] 包括空格在內的任意空白字符 [:punct:] 既不在[:alnum:]又不在[:cntrl:]中的任意字符 [:print:] 任意可打印字符 [:graph:] 與[:print:]相同,但不包括空格
重複元字符
* 0個或多個匹配 + 1個或多個匹配 ? 0個或1個匹配 {n} 指定數目的匹配 {n,} 很多於指定數目的匹配 {n,m} 匹配數目的範圍,m不大於255
select * from osc_users where name regexp '^[[:digit:]]{4}' order by id;/*name字段開始處包含4個數字*/
定位符,匹配特定位置的文本
^ 文本的開始 $ 文本的結尾 [[:<:]] 詞的開始 [[:>:]] 詞的結尾
^ 還有另外一個含義,在集合的開始處放置一個^表示否認,例如[^123]表示匹配除了字符1,2,3之外的任何東西
經過計算字段輸出由表內字段值計算出的內容
拼接(concatenate)字段:將字段值聯接到一塊兒構成單個值,可以使用Concat()函數拼接兩個列
select name, CONCAT(province,' ',city) from osc_users;/*拼接字段*/
使用別名,AS關鍵字
select id,name,concat(province,': ',city) as address from osc_users;/*將字段拼接爲一個address別名字段*/
執行算數計算,對字段進行 +,-,*,/ 運算
經常使用的文本處理函數
Length() 返回字符串的長度 Left() 返回串左邊的字符 Right() 返回串右邊的字符 Lower() 將串轉換爲小寫 Upper() 將串轉換爲大寫 Trim() 去掉字符串兩端空格 LTrim() 去掉串左邊的空格 RTrim() 去掉串右邊的空格 Locate() 找出串的一個字串 SubString() 返回子串的字符 Soundex() 返回發音類似的值
日期與時間處理函數,格式xxxx-xx-xx
Date() Year() Month() Day() Hour() Minute() Second() Now() CurDate() CurTime()
select name,reg_time from osc_users where DATE(reg_time)='2008-09-04';/*Date()返回datetime類型字段的時間部分*/
選擇日期區間, 使用 between and
select name,reg_time from osc_users where DATE(reg_time) between '2008-09-01' and '2008-09-30';
另外一種方法
select name,reg_time from osc_users where YEAR(reg_time)=2008 and MONTH(reg_time)=9;
數值處理函數
僅處理數值數據,通常用於代數,三角或幾何運算
AVG() 返回某列的平均值 COUNT() 返回某列的行數 MAX() 返回某列的最大值 MIN() 返回某列的最小值 SUM() 返回某列值之和
select COUNT(*) as openidNum from osc_users where type=3;/*計算第三方用戶數量*/
使用distinct 包含不一樣值
select AVG(distinct score) from osc_users;
分組容許把數據分爲多個邏輯組,以便對於每一個組進行彙集計算
數據分組:GROUNP BY
select type,COUNT(*) as typeNum from osc_users GROUP BY type;/*根據type進行分組計算,計算出每一個type對應的行數*/
關於使用GROUNP BY的重要規定:
1. GROUNP BY子句能夠包含任意數目的列,這使得可以對分組進行嵌套,爲數據分組提供更細緻的控制
2. 若是在GROUNP BY子句中嵌套了分組,數據將在最後規定的分組上進行彙總
3. GROUNP BY子句中列出的每一個列都必須是檢索列或有效的表達式(但不能是彙集函數),若是在SELECT中使用表達式,則必須在GROUNP BY子句中指定相同的表達式,不能使用別名
4. 除了彙集計算語句外,SELECT語句中的每一個列都必須在GROUNP BY子句中給出
5. 若是分組列中具備null值,則NULL將做爲一個分組返回。若是列中有多個NULL,它們將分爲一組
6. 子句順序,WHERE GROUNP BY ORDER BY
select type,gender,COUNT(*) as typeNum from osc_users GROUP BY type,gender;/*先根據type進行分組,每一個type再根據gender分組計算*/
過濾分組:HAVING
對GROUP BY分出的組進行過濾,HAVING支持全部WHERE操做符
select gender,COUNT(*) as s from osc_users group by gender HAVING COUNT(*)>=5;/*根據gender進行分組,並過濾出總數大於5的分組*/
select子句順序總結
SELECT FROM WHERE GROUP BY HAVING ORDER BY LIMIT
子查詢:嵌套在其它查詢中的查詢。即做爲另外一個的查詢的查詢條件
SELECT * FROM osc_users WHERE id IN (SELECT ......)
做爲計算字段查詢
SELECT cust_name, cust_state, (SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name;
關係表
大量一類相同數據應抽離出來另外分表,提供一個主鍵id給主表做爲外鍵,從而創建關係表
等值聯接
SELECT vend_name, prod_name, prod_price FROM vendors, products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name, prod_name;
內部聯接
SELECT vend_name, prod_name, prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id;
right join, left join, inner join三者區別
inner join:返回兩表聯接字段相等處的數據
right join:返回左表聯接字段相等處的數據和右表全部數據,左表無對應數據處用null代替
left join:返回左表全部數據和右表聯接字段相等處的數據,右表無對應數據處用null代替
SELECT b.user,COUNT(*) AS num FROM osc_tweet_topics a right join osc_opt_logs b ON a.log = b.id WHERE a.ref_id = 0 AND ref_type =100 AND a.title = "世界盃" AND obj_type = 100 group by b.user;
聯接多個表。先列出全部表,再定義表之間的關係
SELECT prod_name, vend_name, prod_price, quantity FROM orderitems, products, vendors WHERE products.vend_id = vendors.vend_id AND orderitems.products = products.prod_id AND order num =20005;
表別名:使用表別名可縮短sql語句
自聯接:
假如發現某物品(其ID爲DTNTR)存在問題,所以想知道生產該物品的供應商的其它物品是否也存在問題。此查詢要求先找到生產ID爲DTNTR的物品的供應商,而後找出這個供應商生產的其它物品
方法一,使用子查詢
SELECT prod_id,prod_name FROM products WHERE vend_id = (SELECT vend_id WHERE prod_id = 'DTNTR');
方法二,使用自聯接。以下例,先根據vend_id聯接兩個表,再根據p2.prod_id過濾數據
SELECT p1.prod_id, p1.prod_name FROM products p1, products p2 WHERE p1.vend_id = p2.vend_id AND p2.prod_id = 'DTNTR';
雖然這兩種方法結果是相同的,可是有時候處理聯接遠比處理子查詢快的多,應該試一下兩種方法,以肯定哪種性能更好
天然聯接:
不管什麼時候對錶進行聯接,應該至少有一個列出如今不止一個表中(被聯接的列)。
內部聯接返回全部數據,甚至相同的列屢次出現。天然聯接排除屢次出現,使每一個列只返回一次。這個操做是手動完成的,主表使用通配符,其它表使用一個明確的子集
外部聯接:
聯接包含那些在相關表中沒有關聯行的行,這類聯接稱爲外部聯接
LEFT OUTER JOIN
RIGHT OUTER JOIN
使用帶彙集函數的聯接
SELECT customers.cust_name,customers.cust_id,COUNT(orders.order_num) AS num_ord FROM customers INNER JOIN orders ON customers.cust_id = orders.cust_id GROUNP BY customers.cust_id;
本章講述如何利用UNION操做符將多條SELECT語句組合成一個結果集