MySQL的查詢
(1)概覽SELECT語句的語法:
SELECT
列1 as '別名1',
列2 as '別名2',
....
FROM
table_1(表1)
WHERE
條件1 AND/OR 條件2
GROUP BY 子句
ORDER BY 子句
HIVING 子句
LIMT 子句
(2) SELECT語句各子句的描述:
SELECT
之后是逗號分隔列或星號(*)的列表呆细,表示要返回所有列耙厚。
FROM
指定要查詢數(shù)據(jù)的表或視圖各拷。
JOIN 根據(jù)某些連接條件從其他表中獲取數(shù)據(jù)骨田。
WHERE
過濾結果集中的行爬迟。
GROUP BY 將一組行組合成小分組,并對每個小分組應用聚合函數(shù)部服。
HAVING 過濾器基于GROUP BY子句定義的小分組哟忍。
ORDER BY 指定用于排序的列的列表。
LIMIT 限制返回行的數(shù)量瑟押。
具體釋義:
一:select語句:
下載示例數(shù)據(jù)庫:http://www.yiibai.com/downloads/yiibaidb.zip
1.1:查詢名字秘噪,姓氏,職位勉耀,并設置別名
SELECT
employees.lastName AS '名',
employees.firstName AS '姓',
employees.jobTitle AS '職位'
FROM
employees;
1.2:select 用戶case替換查詢結果中的數(shù)據(jù)
SELECT
CASE
WHEN employees.employeeNumber <= 1100 THEN '老員工'
WHEN employees.employeeNumber BETWEEN 1100 AND 1500 THEN '新員工'
ELSE '實習生'
END AS '員工編號',
employees.lastName AS '姓',
employees.firstName AS '名'
FROM
employees;
可以和其他語句搭配指煎,語法遵循:
case
when 條件1 then 執(zhí)行結果1
when 條件2 then 執(zhí)行結果2
else 執(zhí)行結果3
end
1. 3:計算列的值
SELECT
CASE
WHEN employees.employeeNumber <= 1100 THEN '老員工'
WHEN employees.employeeNumber BETWEEN 1100 AND 1500 THEN '新員工'
ELSE '實習生'
END AS '員工編號',
employees.lastName AS '姓',
employees.firstName AS '名',
employees.officeCode as '舊辦公室編號',
employees.officeCode + 100 as '新辦公室編號' #對字段進行計算
FROM
employees;
運行結果:
1.4:消除結果中重復的行
SELECT
DISTINCT employees.officeCode AS '辦公室'
FROM
employees;
只能單獨使用,不能和其他查詢條件一起使用便斥。
1.5:聚合函數(shù)
聚合函數(shù)對一列或者一組值進行計算至壤,然后返回單個值,其中除了COUNT函數(shù)外枢纠,其他函數(shù)都會忽略空值像街。
補充:
如果SELECT代碼中有GROUP BY語句,那么聚合函數(shù)會依次對每一分組都產(chǎn)生作用晋渺,
如果沒有那么只會生成一行作為結果镰绎。
示例:
(1):無GROUP BY語句
(2)::有GROUP BY語句
如果使用count(*)結果就是23,因為包含了NULL
1.6:聚合函數(shù)的基本計算(SUM木西、AVG畴栖、MAX、MIN)
公式為:MAX / MIN ALL / DISTINCT 表達式:
SELECT
COUNT(DISTINCT products.productCode) AS '去重商品數(shù)',
COUNT(products.productCode) AS '商品數(shù)',
MAX(products.buyPrice) AS '最大商品價格',
MIN(products.buyPrice) AS '最小商品價格',
AVG(products.buyPrice) AS '商品價格平均值'
FROM
products
運行結果:
1.7:聚合函數(shù)計算標準差八千,方差
SELECT
COUNT(DISTINCT products.productCode) AS '去重商品數(shù)',
COUNT(products.productCode) AS '商品數(shù)',
VARIANCE(products.buyPrice) AS '商品價格方差',
STDDEV(products.buyPrice) AS '商品價格標準差',
AVG(products.buyPrice) AS '商品價格平均值'
FROM
products
variance:方差吗讶,
stddev:標準偏差
運行結果:
二:FROM子句
select看的查詢表對象由from子句指定
2.1:全鏈接
基本語法:"左表 ,右邊"
#查詢每個辦公室的員工名字和辦公室電話和地址
SELECT
offices.officeCode AS '辦公室名字',
employees.firstName AS '姓',
employees.lastName AS '名',
offices.phone AS '電話',
offices.addressLine1 AS '地址1',
offices.addressLine2 AS '地址2'
FROM
employees,
offices
2.2:交叉鏈接
基本語法:左表 cross join 右邊;
SELECT
employees.employeeNumber,
FROM
items cross join employees;
最終結果:
交叉連接和全連接都是一樣的燎猛,原理是:從第一張表中循環(huán)取出第一行,都去另外一張表的每一行進行匹配照皆,匹配的結果都保留重绷,最終中間表會變得非常大,這樣的結果成為笛卡爾積膜毁。
可以看到第一行的Diane員工跟6個辦公室信息發(fā)生了匹配昭卓,也就是23行 *6行剛好是161條信息。
這樣的結果是沒有實際意義的瘟滨。我們需要的是編號相等的部分候醒。
emp.deptno = dept.deptno
設定emp.deptno = dept.deptno,又叫等值鏈接
#查詢每個辦公室的員工名字和辦公室電話和地址
SELECT
offices.officeCode AS '辦公室名字',
employees.firstName AS '姓',
employees.lastName AS '名',
offices.phone AS '電話',
offices.addressLine1 AS '地址1',
offices.addressLine2 AS '地址2'
FROM
employees cross join offices
WHERE
employees.officeCode = offices.officeCode
···
通過where條件篩選剔除了很多無效的值室奏,雖然這樣能用火焰,但是where條件效率沒有內(nèi)連接高。
運行結果:
2.3:內(nèi)連接
基本語法:左表 + [inner + join]+ 右表 + on + 左表.字段 = 右表.字段;
用內(nèi)連接查詢每個辦公室的員工名字和辦公室電話和地址
···
SELECT
offices.officeCode AS '辦公室名字',
employees.firstName AS '姓',
employees.lastName AS '名',
offices.phone AS '電話',
offices.addressLine1 AS '地址1',
offices.addressLine2 AS '地址2'
FROM
employees
INNER JOIN offices ON employees.officeCode = offices.officeCode
····
內(nèi)連接是將左邊的表的一行取出胧沫,然后和右表的每一行匹配昌简,可以想象是生成了一個中間表,如果ON的條件是相等的绒怨,就將兩個表匹配行留下纯赎,不相等就都丟棄。跟上面的等值鏈接一個道理南蹂,歸根結底都是笛卡爾積犬金,都是不保留字段值不相等的部分,但是效率高六剥。
運行結果:
2. 4:外連接
基本語法:
左查詢:
左表 + [left join ] + 右表 + on + 左表 . 字段 + 右表 . 字段晚顷;
left:以左表為主表里面的記錄全部取出,將右表拿去匹配疗疟,如果字段 ON相等則留下该默,如果匹配失敗則留NULL。
左表 + [ right join ] + 右表 + on + 左表 . 字段 + 右表 . 字段
right:與left相反策彤。
(1)左查詢示例:
(2)右查詢示例:
三:where限制查詢:
3.1單一條件限制查詢
查詢銷售崗位的員工名字
SELECT
employees.lastName,employees.firstName,employees.jobTitle
FROM
employees
WHERE
jobTitle = 'sales Rep'
where 不能條件語句中不能使用別名栓袖,因為他是直接從磁盤中讀取,不要的丟棄店诗,只有HIVING GROUP 才可以裹刮。
運行結果:
3.2 多條件限制查詢
在語句中使用 ’AND‘或者 'OR'連接起來。
查詢銷售崗位并且辦公室代碼為1的員工庞瘸。
SELECT
lastname, firstname, jobtitle
FROM
employees
WHERE
jobtitle = 'Sales Rep' AND officeCode = 1;
運行結果:
3.3運算符查詢
運算符語法:
(1)查詢使用不等于(!=)運算符來獲取不是銷售代表的其它所有員工:
SELECT
lastname, firstname, jobtitle
FROM
employees
WHERE
jobtitle != 'Sales Rep';
運行結果:
(2)替換查詢結果中的數(shù)據(jù)
SELECT
employeeNumber AS '員工編號',
lastName AS '姓',
firstName AS '名',
officeCode AS '辦公室名稱',
CASE
WHEN employees.officeCode IS NULL THEN
'未分配'
WHEN employees.officeCode = 1 THEN
'第一間'
WHEN employees.officeCode = 2 THEN
'第二間'
WHEN employees.officeCode = 3 THEN
'第三間'
ELSE
'第四間'
END AS '辦公室名稱',
jobTitle AS '職位'
FROM
employees
WHERE
jobTitle = 'sales Rep'
運行結果:
擴展查詢:
BETWEEN選擇在給定范圍值內(nèi)的值捧弃。
LIKE匹配基于模式匹配的值。
IN指定值是否匹配列表中的任何值恕洲。
IS NULL檢查該值是否為NULL塔橡。
Between查詢
(3)查找價格在90和100(含90和100)元范圍內(nèi)的商品
SELECT
productCode, productName, buyPrice
FROM
products
WHERE
buyPrice BETWEEN 90 AND 100;
運行結果:
(4)查找購買價格不在20到100(含20到100)之間的產(chǎn)品梅割,可將BETWEEN運算符與NOT運算符組合使用霜第,如下:
SELECT
productCode, productName, buyPrice
FROM
products
WHERE
buyPrice NOT BETWEEN 20 AND 100;
運行結果:
(5)計算2013-01-01到2013-01-31日期之間的訂單葛家。
當使用 BETWEEN運算符 計算 DATE數(shù)據(jù)類型時,應把計算的字符串類型轉換成DATE類型
select
orders.orderNumber,orders.requiredDate,orders.`status`
FROM
orders
WHERE
requiredDate BETWEEN CAST('2013-01-01' AS DATE) AND CAST('2013-01-31' AS DATE);
#值得注意的是在這里泌类,運行的時候報錯癞谒,排查時發(fā)現(xiàn)原來status在MySQL中是關鍵字。
運行結果:
四:MySQL的相似查詢'LIKE'
LIKE運算符有兩種通配符:
"%" 匹配若干字符
“_” 匹配單個字符
4.1 搜索名字以字符a開頭的員工信息
SELECT
employeeNumber, lastName, firstName
FROM
employees
WHERE
firstName LIKE 'a%';
運行結果:
4.2 查找名字以arry結尾的員工
SELECT employees.employeeNumber,employees.lastName,employees.firstName
FROM
employees
WHERE
employees.firstName LIKE '_arry';
運行結果:
4.3 通配符的轉義:
有時想要匹配的數(shù)據(jù)包含通配符刃榨,例如10%弹砚,_20等這樣的字符串時∈嘞#可以使用“\”進行轉義桌吃,如要轉移成特定數(shù)據(jù)類型,可以使用ESCAPE語句苞轿。
不指定類型:
select products.productCode,products.productName
from
products
WHERE
productCode LIKE '%\_20%';
運行結果:
4.4 使用ECASPE指定新的轉義字符"$"
查詢包含“_20”的商品編號:
select products.productCode,products.productName
from
products
WHERE
productCode LIKE '%$_20%' ESCAPE '$';
運行結果:
4.4 “IN”查詢
比OR代碼更簡潔
SELECT offices.officeCode,offices.city,offices.phone,offices.country
from
offices
WHERE
country IN ('USA','china');
運行結果:
五:分組語句 GROUP BY
GROUP BY語句是根據(jù)表中字段進行分組茅诱,如果字段的值相同悉患,那么就聚合在一個組栅组,不同的放在另一個組,也就是按值分組贞瞒。與count契邀,max摆寄,min,avg,sum等統(tǒng)計函數(shù)組合使用坯门。
cout():統(tǒng)計分組后微饥,每組的總記錄數(shù);
max():統(tǒng)計每組中的最大值古戴;
min():統(tǒng)計每組中的最小值欠橘;
avg():統(tǒng)計每組中的平均值;
sum():統(tǒng)計每組中的數(shù)據(jù)總和允瞧。
六:HIVING 語句
HIVING能做where的所有事情简软,并且能使用別名:
#查詢辦公室中人數(shù)大于4人的編號
SELECT
employees.officeCode AS '辦公室編號',
COUNT(DISTINCT employeeNumber) AS '人數(shù)'
FROM
employees
GROUP BY
officeCode
HAVING 人數(shù)> 4
運行結果:
七: 排序語句 ORDER BY
SELECT
payments.customerNumber AS '顧客編號',
COUNT(payments.customerNumber) AS '顧客購買次數(shù)',
avg(payments.amount) '顧客購買單價',
sum(payments.amount) '顧客購買總數(shù)'
FROM
payments
GROUP BY
payments.customerNumber
ORDER BY
顧客購買次數(shù) DESC,customerNumber DESC;
升序:ASC(ascend:上升),降序DESC(descend:下降)
運行結果:
八:查詢范圍語句 LIMT
限制輸出的范圍述暂,降低服務器的消耗痹升。
(1)限制多少條結果:
-- 查詢表 student 中的全部記錄
select * from student;
-- 查詢表 student 中的 3 條記錄
select * from student limit 3;
運行結果:
(2)限制范圍:
-- 查詢表 student 中的記錄
select * from student limit 0,2;
-- 查詢表 student 中的記錄
select * from student limit 2,2;
運行結果: