SQL查詢語句詳解(一)
一、基本語法
Select select_list
From table_name
Where condition_expression
Group by group_columns
having condition_expression
Order by sort_columns
二、查詢實例
- 查詢所有字段
- 查詢指定字段
- 用DISTINCT去除結果中的重復行
- 查詢指定數據
- 帶有in關鍵字的查詢
- 帶between and的范圍查詢
- 帶like的字符匹配查詢
表1:學生
- 結構
- 數據
表2:商品表1
- 結構:
- 數據:
表3:商品表2
- 結構:
- 數據
表4:教師
- 結構:
- 數據
- 數據分析需求
1)查詢所有學生的詳細信息
SELECT *from 學生;
2)查詢學生的學生號,姓名與專業
select 學生號,姓名,專業 from 學生;
3)從商品表1中查詢出每一種商品的價值
SELECT 商品代號,單價,數量,單價*數量 as 總價 from 商品表1;
4)查詢本商品表1中商品的種類
SELECT distinct 分類名 from 商品表1;
5)從商品表1中查詢出分類名為"電視機"的所有商品
select * from 商品表1 where 分類名 ='電視機';
6)從商品表1中查詢出單價低於2000元的每一種商品代號,分類名和單價
select 商品代號,分類名,單價 from `商品表1` where 單價<=2000;
7)從商品表2中查詢出產地為北京、山西、無錫的所有商品
SELECT * from 商品表2 where 產地 in('北京','山西','無錫');
8)從商品表1中查詢出商品代號以字符串"dsj"開頭的所有商品(考察like模糊查詢及通配符%)
select * from 商品表1 where 商品代號 like 'DSJ%'
MySQL中的通配符;%, _ (下划線),
9)從商品表1中查詢單價在1000到2000之間的所有商品
select * from 商品表1 where 單價 between 1000 and 2000;
10)查詢所有姓張的學生的詳細信息
select * from 學生 where 姓名 like '張_';
11)從商品表1中查詢出單價大於1500,同時數量大於等於10的商品
select * from 商品表1 where 單價 >=1500 and 數量 >=10;
12)從教師表中查詢聯系電話為空的教師信息
select * from 教師 where 聯系電話 is null;
13)從選課表中查詢按課程號的升序,同一課程按成績降序排列
select * from 選課 order by 課程號 asc,成績 desc;
14)從學生表中查詢各個專業的人數
select 專業,count(*) as 人數 from 學生 group by 專業
15)從學生表中查詢出專業的學生數多於1人的專業名及人數
select 專業,count(*) as 人數 from 學生 group by 專業 having count(*)>1
select 專業,count(*) as 人數 from 學生 group by 專業 having 人數>1
16)從選課表中查詢成績最高前三位
select * from 選課 order by 成績 desc limit 3
17)查詢各個專業男女人數各是多少
select 專業,性別,count(*) as 人數 from 學生 group by 專業,性別
18)從商品表1中查詢出所有商品的最大數量、最小數量、平均數量及數量總和
select max(數量) as 最大數量,min(數量) as 最小數量,avg(數量) as 平均數量,sum(數量) as 數量總和 from 商品表1
19)從商品表1中查詢出分類名為“電視機”的商品的種數、最高價、最低價及平均價
select 分類名,count(分類名) as 種數,max(單價) as 最高價,min(單價) as 最低價,avg(單價) as 平均價 from 商品表1 where 分類名='電視機'
20)查詢出產地為南京或無錫的所有商品的商品代號、分類名、產地和品牌
select a.商品代號,b.分類名,a.產地,a.品牌 from 商品表2 a inner join 商品表1 b on a.商品代號=b.商品代號 where a.產地 in ('南京','無錫')
或
select a.商品代號,b.分類名,a.產地,a.品牌 from 商品表2 a,商品表1 b
where a.商品代號=b.商品代號 and a.產地 in ('南京','無錫')
21)從教學庫中查詢出選修了課程名為“操作系統”課程的每個學生的姓名
select b.姓名,c.課程名 from 選課 a
inner join 學生 b on a.學生號=b.學生號
inner join 課程 c on a.課程號=c.課程號 where c.課程名='操作系統' or b.姓名
或
select 姓名,課程名 from 選課 a,學生 b,課程 c where a.學生號=b.學生號 and a.課程號=c.課程號 and c.課程名='操作系統'
22)從教學庫中查詢出所有學生的選課情況,要求沒選修任何課程的學生信息也要
反映出來(左,右連接)
select *from 學生 a left join 選課 b on a.學生號=b.學生號
select * from 選課 a right join 學生 b on a.學生號=b.學生號
23)從教學庫中查詢出選修了課程名為“操作系統”的所有學生(帶in的子查詢)
select * from 學生 where 選修了課程名為“操作系統”的所有學生
進一步分析:
select * from 學生 where 學生號 in (所有選修了操作系統的學生號名單)
所有選修了操作系統的學生號名單?
select a.學生號 from 選課 a,課程 b where a.課程號=b.課程號 and 課程名='操作系統'
最終的代碼:
select * from 學生 where 學生號 in (select a.學生號 from 選課 a,課程 b where a.課程號=b.課程號 and 課程名='操作系統')
24)查詢出比所有商品單價的平均值要高的全部商品(比較運算符)
select * from 商品表1 where 單價>(select avg(單價) from 商品表1)
25)從教學庫中查詢出選修至少一門課程的所有學生(帶exists(的子查詢)
select * from 學生 where exists(select * from 選課 where 選課.學生號=學生.學生號)
或
select * from 學生
where 學生號 in ( select distinct 學生號 from 選課 )
26)從教學庫中查詢出選修了課程名為“C++語言“的所有學生的姓名和成績(any子查詢)
select b.姓名,c.課程名,a.成績 from 選課 a
inner join 學生 b on a.學生號=b.學生號
inner join 課程 c on a.課程號=c.課程號 where c.課程名='C++語言'
select 姓名,成績 from 學生 join 選課 on 學生.學生號=選課.學生號
where 課程號=any(select 課程號 from 課程 where 課程名='C++語言')
27)從商品表1中查詢出單價比分類名為 “洗衣機”的所有商品單價都高的商品
select *from 商品表1 where 單價>all (select 單價 from 商品表1 where 分類名='洗衣機')
select * from 商品表1 where 單價>(select max(單價)from 商品表1 where 分類名='洗衣機')
28)從商品表1中查詢出單價比分類名為“洗衣機”的所有商品的單價 其中一種 高的商品
select * from 商品表1 where 單價>any(select 單價 from 商品表1 where 分類名='洗衣機') and 分類名<>'洗衣機'
29)查詢出每種商品的總價值,並按降序排列
select 分類名,sum(單價*數量) as 總價 from 商品表1 group by 分類名 order by 總價 desc
30)查詢至少選修了王明所選修的所有課程的學生
-- 王明選修的課程
select a.姓名,b.課程號 from 學生 a,選課 b where a.學生號=b.學生號 and 姓名='王明'
-- 終極答案
select*from 學生
where 姓名 !='王明' and 學生號 in
(select 學生號 from 選課 where 課程號 in (select 課程號 from 選課,學生 where 選課.學生號=學生.學生號 and 姓名='王明')
group by 學生號 having count(*)=(select count(*) from 選課,學生 where 選課.學生號=學生.學生號 and 姓名='王明'))
-- 終極答案2
select*from 學生
where 姓名 !='王明' and 學生號=any
(select 學生號 from 選課 where 課程號 in (select 課程號 from 選課,學生 where 選課.學生號=學生.學生號 and 姓名='王明')
group by 學生號 having count(*)=(select count(*) from 選課,學生 where 選課.學生號=學生.學生號 and 姓名='王明'))
31)查找選擇了課程編號為101和102的學生,把其學號顯示出來
合並查詢(union去除重復記錄)
select * from 選課成績 where 課程編號 in(101,102)
select * from 選課成績 where 課程編號='101'
union
select *from 選課成績 where 課程編號='102'
union
select *from 選課成績 where 課程編號='103'
如果希望上述結果中顯示課程名稱,sql語句如下:
select a.*,b.課程名稱 from 選課成績 a,課程2 b
where a.課程編號=b.課程編號 and a.課程編號='101'
union
select a.*,b.課程名稱 from 選課成績 a ,課程2 b
where a.課程編號=b.課程編號 and a.課程編號='102'
32)把test1和test2表的數據合並在一起
select * from test1
union
select * from test2
合並查詢(union all 保留重復記錄)
select * from test1
union all
select * from test2
三、其他補充
33)創建如下表並插入測試數據
要求對此表查詢,顯示如下結果:
顯示結果:
姓名 語文 高數 英語
李勇 90 70 80
劉晨 60 77 96
select a.name as 姓名,a.score as 語文,b.scoreas 高數,c.score as 英語
from
grade a,grade b,grade c
where
a.name =b.name and b.name=c.name
and
a.subject='語文' and b.subject='高數' and c.subject='英語'
34)在SQL中使用正則示例
查詢以DS開頭的產品
select * from 商品表1 where 商品代號 regexp '^DS'
查詢以冰箱結尾的
select * from 商品表1 where 分類名 regexp '冰箱$'
查詢商品代號中包含B字符的產品
select * from 商品表1 where 商品代號 regexp 'B.'
查詢商品代號中包含XT
select * from 商品表1 where 商品代號 REGEXP '[XT]'
查詢商品代號中不包含XT的
select * from 商品表1 where 商品代號 REGEXP '[^XT]'
查詢test表中id不包含a-h之間任意一個字符的學員
select * from test where id REGEXP '[^a-h]'
查詢出商品表1中商品代號包含DB,XY,AH
select * from 商品表1 where 商品代號 REGEXP 'DB|XY|AH'
查詢商品表中至少有1個X的商品
select * from 商品表1 where 商品代號 REGEXP 'X{1}'
查詢商品表1中商品代號中,XY最少出現1次,XY最多出現3次
select * from 商品表1 where 商品代號 REGEXP 'XY{1,3}'
35)高級插入語句
insert into test1(id,name,age) select id, name,age from test2 where id =106
36)replace語句
用replace插入一條記錄時,如果不重復,replace就和insert
的功能一樣,如果有重復記錄,replace就使用新記錄的值來替換原來的記錄值。
語法:
replace tablename(列名...)VALUES(列值);
或
replace tablename SET column_namel =value1,column_name2 = value2,..;
示例:
replace test1(id,name ,age) values (104,'陳陽',22)
37) 將電子專業的所有學生各門課成績加5分(techdb 成績表)
update 選課 set 成績=成績+5
where 學生號 in (select 學生號 from 學生 where 專業='電子')
13、將員工表中工齡大於30年的工資全部上調20%(northwind)
select 姓名,部門,year(now())-year(雇佣日期) as 工齡 from
員工 where year(now())-year(雇佣日期)>30
update 員工 set 目前薪資=目前薪資*1.2 where year(now())-year(雇佣日期)>30
14、將比生產制造部員工最高工資還要高的員工工資下調20%
以下這種寫法是錯誤的:
以下代碼是錯誤的:
select 姓名,部門,目前薪資 from 員工
where 目前薪資>(select max(目前薪資) from 員工 where 部門='生產制造部')
正確的寫法是:
update 員工 set 目前薪資=目前薪資*0.8
where 目前薪資>(select t.最高工資 from (select max(目前薪資) as 最高工資 from 員工 where 部門='生產制造部') t)
14、將比生產制部中工資排名前三的員工工資任意一個高的員工工資下調10%
select 姓名,部門,目前薪資 from 員工 where 目前薪資>
any(select 目前薪資 from 員工 where 部門 ='生產制造部' order by
目前薪資 desc limit 3) and 部門<>'生產制造部'
正確的代碼是:
update 員工 set 目前薪資=目前薪資*0.9 where 目前薪資>
any(select t.目前薪資 from (select 目前薪資 from 員工 where 部門 ='生產制造部' order by
目前薪資 desc limit 3) t ) and 部門<>'生產制造部'
如果想把以上條件的員工刪除,則SQL代碼是:
delete from 員工 where 目前薪資>
any(select t.目前薪資 from (select 目前薪資 from 員工 where 部門 ='生產制造部' order by 目前薪資 desc limit 3) t ) and 部門<>'生產制造部'