MySql查詢
一、SELECT
1.基礎用法
select * from table
select name from table
select name,id from table
使用別名
select T.name as Name,T.id from table as T
2.limit限制
limit and offset
limit 5 :返回不多於5行
limit 5,5 :返回第5個以後的5行
limit 3 offset4 :在第4行後面取3行
語句1:select * from student limit 9,4
語句2:slect * from student limit 4 offset 9
// 語句1和2均返回表student的第10、11、12、13行
//語句2中的4表示返回4行,9表示從表的第十行開始
例子
編寫一個 SQL 查詢,獲取 Employee
表中第二高的薪水(Salary)
select DISTINCT Salary from Employee order by Salary desc limit 1 offset 1
3.order排序
默認升序 order by desc降序 order by asc升序
1.默認排序
根據name默認升序
select name from table order by name;
優先根據id默認升序,id一樣再根據name默認升序
select id name tel from table order by id,name
2.desc 排序
優先按id降序,若id一致則默認按name升序(name不在desc範圍)
select id name tel from table order by id desc,name
3.Distinct 去重
從表中查詢數據時,可能會收到重複的行記錄。爲了刪除這些重複行,可以在SELECT
語句中使用DISTINCT
子句。
DISTINCT
子句的語法如下:
SELECT DISTINCT columns FROM table_name
WHERE where_conditions;
去除name重複的結果
select distinct name from user
去除 name id 都重複的結果 (id重複name不重複的不去除)
select distinct name, id from user
select AVG(distinct price) as avg_price from products;
Distinct必須使用列名 如下 所示是錯誤的 也不能用於COUNT(*)
select Count(distinct) as count from products;
正確做法
select Count(distinct price) as count from products;
4.where過濾
1.基本操作
select * from table where id=4;
select * from table where id between 5 and 10;
2.where操作符:
= , > , < , >= , <= , != , between
select * from table where id is null
3.組合where
1.and
select * from table where id>=7 and name='yukai'
2.or
select * from table where id>=7 or name='yukai'
3.in
in功能和or相當 但多個參數使用時更方便,不需要顧慮優先級
in可包含其他where字句
select prod_name,prod_price
from product
where vend_id in(1002,1003)
order by prod_name;
4.not
select prod_name,prod_price
from product
where vend_id not in(1002,1003)
order by prod_name;
select * from table where id not between 5 and 10;
4.組合計算次序
計算價格10及以上且由1002或1003製造的所以產品
錯誤寫法 計算次序中and優先級高於or
select prod_name,prod_price
from product
where vend_id = 1002 or vend.id=1003
and prod_price>=10;
正確寫法
select prod_name,prod_price
from product
where ( vend_id = 1002 or vend.id=1003 )
and prod_price>=10;
5.通配符
1.like
任意以jet開頭的prod_name
select prod_id , prod_name
from product
where prod_name like 'jet%'
任意 包含jet的prod_name
select prod_id , prod_name
from product
where prod_name like '%jet%'
a開頭e結尾的prod_name
尾部空格會干擾判斷 如’awwe '不會被查找出來
select prod_id , prod_name
from product
where prod_name like 'a%e'
2._
_只匹配一個字符
'aoe’能匹配 'aope’不能匹配 'ae’不能匹配 必須有一個字符
select prod_id , prod_name
from product
where prod_name like 'a_e'
3.注意事項
- 通配符效率低下,儘量使用其他操作符
- 如果一定要使用,不要用在搜索模式的開始處,搜索模式開始處最慢
- 注意通配符位置
5.正則表達式
1.基本字符匹配
包含1000的所有行 如’jetpack 1000’
select name
from product
where name regexp '1000'
.表示匹配任何一個字符
包含.000的所有行 如’jetpack 1000’ ‘jetpack 2000’
select name
from product
where name regexp '.000'
or在正則表達式中爲 |
包含1000和2000和3000的所有行 如’jetpack 1000’ 'jetpack 2000’等
select name
from product
where name regexp '1000|2000|3000'
匹配特定字符 用[ ]
‘1 ton’ ‘2 ton’ '3 ton’匹配
select name
from product
where name regexp '[123] ton'
未完待續。。。。
6.拼接字段Concat()函數
其他sql用的+或者| mysql不同移植時需要注意
輸出name(country) 如 Dave(CN)
select Concat(name,'(',country,')')
from vendors
7.去除尾部空格RTirm()函數
去除name中尾部的所有空格
select Concat(RTirm(name),'(',country,')')
from vendors
8.算數計算
select id ,
item_num,
item_price,
item_prict*item_num as total_price
from orderitems
二、函數
常用函數
Left() 返回左邊字符
Right() 返回左邊字符
Length() 返回長度
Locate() 找出一個字串
Upper() 將串轉化爲大寫
Lower() 將串轉化爲小寫
LTrim() 去掉左邊的空格
RTrim() 去掉右邊的空格
Soundex() 返回串的Soundex值
SubString() 返回字串的字符
事件日期函數
默認格式 YYYY-MM-DD
AddDate() 增加一個日期(天,周等)
AddTime() 增加一個使勁按 (時 ,分,秒等)
CurDate() 返回到當前日期
CurTime() 返回到當前時間
Date() 返回日期時間的日期部分
DateDiff() 計算兩個日期之差
Date_Add() 高度靈活的日期運算函數
Date_Format() 返回一個格式化的日期或時間串
Day() 返回一個日期的天數部分
。。。。。。。。
查找2005-09-01日期的訂單 如2005-09-01 11:30:05
where Date(orderdate) = '2005-09-01'
例子
查找9月所有訂單
select id , num
from orders
where Date(order_date) between '2005-09-01' and '2005-09-30'
select id , num
from orders
where Year(order_date)= 2005 and Month(order_date)=9
數值處理函數
Abs() 返回一個數的絕對值
Cos() 返回一個數的餘旋
Exp() 返回一個數的指數值
Mod() 返回除操作的餘數
Pi()
Rand()
Sin()
Sqrt()
Tan
三、彙總數據
聚合函數彙總數據比客戶機應用程序中快得多
1.聚合函數
AVG() 返回某列平均值
select AVG(price) as avg_price from products
AVG函數忽略值爲null的行
取多個平均值需使用多個AVG函數
select AVG(price) as avg_price , AVG(num) as avg_num from products
COUNT()返回某列行數
COUNT(*)無論是否包含null 都計數
select count(*) as count from products;
COUNT(column)忽略NULL值 若price爲null的行忽略 其他column不管
select count(price) as count from products;
MAX() 返回某列最大值
select Max(price) as max from products;
MIN() 返回某列最小值
select min(price) as min from products;
SUM() 返回某列之和
select sum(price) as total_prict from products;
select sum(num*price) as total_prict from products;
2.組合聚合函數
select count(*) as count , min(price) as price_min, max(num) as num_max
from products;
四、分組數據
1.GROUP BY
下面的例子返回name爲C03提供的產品數目
select count(*) as count
from products
where name='C03'
如果要返回每個供應商提供的產品數目怎麼辦 或者返回10個以上產品的供應商怎麼辦
select name,count(*) as count from products group by name;
返回數據
name count
C01 1
C02 1
C03 2
C05 4
select num,name from products order by name;
用來和下面嵌套分組數據對比
C01 100
C02 100
C03 40
C03 80
C04 100
C05 60
C05 100
C05 100
C05 100
C06 100
嵌套group by 先根據name分組 然後再在name分組裏面根據num分組
select num,name,count(*) as count from products group by name,num;
name num count
C01 100 1
C02 100 1
C03 40 1 C03中有兩種num 所以分組 40 和80
C03 80 1
C04 100 1
C05 60 1
C05中有兩種num 所以分組60 和100, 還有2個100因爲一樣就不重新分組了 count 3
C05 100 3
C06 100 1
- group by 字句可以包含任意數目列
- group by嵌套分組,數據將在最後規定的分組上進行彙總
- group by 子句中列出的每個列都必須是檢索或者有效表達式(不能是聚合函數)。如果在select中使用表達式,則必須在group by中指定相同的表達式,不能使用別名。
- select中的每個列都必須在group by中給出 如
select name,num,count(*) as count from products group by name;
-- num 沒有在group by中給出 計算出來num列是混亂的 如C05 num有 60 100 100 100
-- 計算出來爲 C05 60 4
- 如果分組有null值,則null將作爲一個分組返回。如果列中有許多行null值,他們將分爲一組返回
- group by字句必須出現在where字句之後,order by字句之前
with rollup 獲得每個分組彙總級別的值
select name,count(*) as count from products group by name with rollup;
C01 1
C02 1
C03 2
C04 1
C05 4
C06 1
null 10
2.HAVING
所有where字句條件having都能使用
select name,count(*) as count
from products
group by name
having count(*)>=2;
C03 2
C05 4
-
having與where的差別
-
where在數據分組前進行過濾
-
having在數據分組後進行過濾
-
where排除的行不包括在分組中,這有可能改變計算值,從而影響having字句基於這些值的判斷
-
在where過濾name=’C03 ‘以外的值後再進行分組再進行having過濾
select name,count(*) as count
from products
where name='C03'
group by name having count(*)>=2;
ORDER BY | GROUP BY |
---|---|
排序產生的輸出 | 分組行。但輸出可能不是分組的順序 |
任意列都可以使用(甚至非選擇的列都可以使用) | 只可能使用選擇列或者表達式列,而且必須使用每個選擇表達式 |
不一定需要 | 如果與聚合函數一起使用(或表達式),則必須使用 |
不要依賴group by 排序
五、select子句順序
字句 | 是否必須使用 |
---|---|
SELECT | 是 |
FROM | 僅在從表選擇數據時使用 |
WHERE | 否 |
GROUP BY | 僅在按組計算聚集時使用 |
HAVING | 否 |
ORDER BY | 否 |
LIMIT | 否 |
六、子查詢
select cust_id from orders where order_num in (
select order_num from orderitems where prod_id = 'TNT2');
查找所有用戶的訂單數
在custmors中查找用戶姓名及狀態和訂單數(訂單數由子查詢根據customers中查找到的用戶ID和orders中的ID比較一致的計數)
select cust_name , cust_state,(
select count(*) from orders.cust_id = customers.cust_id ) as orders from customers order by cust_name;
七、組合查詢
UNION
select vend_id,prod_id,prod_price from products where prod_price <=5;
等價
select vend_id,prod_id,prod_price from products where prod_price <=5 union
select vend_id,prod_id,prod_price from products where vend_id in(1001,1002);
Union規則
- 必須由兩條或兩條以上的select語句組成,語句中間由union分隔;
- union中每個查詢必須包含相同的列、表達式或者聚集函數。(不過每個列不需要以相同的次序列出)
- 列數據類型必須兼容:類型不必完全相同,但必須是DBMS可以隱含的轉換的類型
- union自動去除重複的行 如果不需要去重 使用union all
如果確定要某個條件的匹配行全部出現(包括重複行),則必須使用UNION ALL而不是where
Order by 使用在最後一條select語句後面
八、全文本搜索
1.全文本搜索
- 需要使用mysql MyISAM引擎。
like關鍵字和正則表達式搜索有缺陷:
- 性能非常耗時
- 不能明確控制
- 不智能化
啓動全文本搜索支持
create table productnotes(
note_id int not null auto_increment,
prod_id char(10) not null;
note_date datetime not null,
note_text text null,
primary key(note_id),
fulltext(note_text)
)ENGINE=MyISAM;
爲了進行全文本搜索,mysql根據字句fulltext(note_text)的指示對它進行索引。這裏的fulltext索引單個列,如果需要也可以指定多個列。
在定義後 mysql自動維護該索引,在增刪改操作後自動更新。
不要在導入sql數據時使用fulltetx,導入數據完成後修改表結構會快很多。
進行全文本搜索
select note_text from productnotes where Match(note_text) Against('rabbit');
match()指定查找的列 Against指定搜索的表達式
Customer complaint: rabbit has been able to detect trap, food apparently less effective now. |
---|
Quantity varies, sold by the sack load. All guaranteed to be bright and orange, and suitable for use as rabbit bait. |
搜索不區分大小寫,除非使用BINARY表達式
like同樣可完成該簡單操作
select note_text from productnotes where note_text like '%rabbit%';
Quantity varies, sold by the sack load. All guaranteed to be bright and orange, and suitable for use as rabbit bait. |
---|
Customer complaint: rabbit has been able to detect trap, food apparently less effective now. |
但是
全文本搜索會按照文本匹配的良好順序排序 如rabbit在字符串靠前位置的優先返回
查詢擴展
select note_text from productnotes where Match(note_text) Against('rabbit') with query expansion;
會搜索除rabbit以外 mysql認爲有關的數據
2.布爾文本搜索
布爾搜索提供一下內容的細節:
- 要匹配的詞
- 要排斥的詞
- 排序提示
- 表達式分組
- 另外一些內容
即使沒有FULLTEXT索引也可以使用 但性能緩慢。
select note_text from productnotes where Match(note_text) Against('heavy'in boolean mode) ;
注意括號位置
select note_text from productnotes where Match(note_text) Against('heavy -rope*'in boolean mode);
包含heavy 但不包含任意以rope開始的詞
布爾操作符 | 說明 |
---|---|
+ | 包含,詞必須存在 |
- | 排除,詞必須不存在 |
> | 包含,而且增加等級值 |
< | 包含,而且減少等級值 |
() | 吧詞組成子表達式 |
~ | 取消一個詞的排序值 |
* | 詞尾的通配符 |
“” | 定義一個短語 |
select note_text from productnotes where Match(note_text) Against('+rabbit +bait'in boolean mode);
包含 詞rabbit 和bait
select note_text from productnotes where Match(note_text) Against('rabbit bait'in boolean mode);
沒有操作符 包含這兩個至少一個詞的行
select note_text from productnotes where Match(note_text) Against('"rabbit bait"' in boolean mode);
匹配“rabbit bait”短語
還有很多注意事項 使用時自行查看學習
e_text) Against('heavy -rope*'in boolean mode);
包含heavy 但不包含任意以rope開始的詞
| 布爾操作符 | 說明 |
| ---------- | -------------------- |
| + | 包含,詞必須存在 |
| - | 排除,詞必須不存在 |
| > | 包含,而且增加等級值 |
| < | 包含,而且減少等級值 |
| () | 吧詞組成子表達式 |
| ~ | 取消一個詞的排序值 |
| * | 詞尾的通配符 |
| "" | 定義一個短語 |
~~~mysql
select note_text from productnotes where Match(note_text) Against('+rabbit +bait'in boolean mode);
包含 詞rabbit 和bait
select note_text from productnotes where Match(note_text) Against('rabbit bait'in boolean mode);
沒有操作符 包含這兩個至少一個詞的行
select note_text from productnotes where Match(note_text) Against('"rabbit bait"' in boolean mode);
匹配“rabbit bait”短語
還有很多注意事項 使用時自行查看學習