1. 程式人生 > >MySQL基本語句與經典習題

MySQL基本語句與經典習題

添加 where子句 round tac outer num div 通配符 tinc

SQL語句大全

本文用到的數據(5張表):

customers:

技術分享圖片

orders:

技術分享圖片

orderitems:

技術分享圖片

Products:

技術分享圖片

Vendors:

技術分享圖片

一、檢索數據-select語句
select prod_name from products; #檢索單個列
select prod_id,prod_name,prod_price from products; #檢索多個列
select * from products;#檢索所有列
select distinct vend_id from products; #選擇不同的值,註意distinct作用於所有列而不僅是緊跟在其後的一列

select prod_name from products
limit 5;#返回5行

select prod_name from products
limit 5 offset 5; #返回從第5行起的5行數據:limit 開始 offset 行數

二、註釋
行內註釋:--註釋
行內註釋:#註釋
多行註釋:/*註釋*/

三、排序檢索數據
select prod_name from products
order by prod_name; #按單列排序

select prod_id,prod_price,prod_name from products
order by prod_price,prod_name; #按多個列排序,首先對price排,再對name排,註意僅在多行具有相同的price時才會對name進行排序

select prod_id,prod_price,prod_name from products
order by prod_price desc,prod_name; #對price降序,name升序,註意desc只應用到直接位於其前面的列名

四、過濾數據-where子句
select prod_name,prod_price from products
where prod_price<10; #檢查單個值

where vend_id <>‘DLL01‘; #不匹配檢查
where vend_id !=‘DLL01‘;

select prod_name,prod_price from products
where prod_price between 5 and 10; #範圍性檢查

select prod_name from products
where prod_price is null; #檢查空值

select prod_id,prod_price,prod_name from products
where vend_id=‘DLL01‘ and prod_price<=4; #and操作符

where vend_id=‘DLL01‘ or vend_id=‘BRS01‘; #or操作符

where vend_id in(‘DLL01‘,‘BRS01‘); #in操作符,與or等價

where not vend_id=‘DLL01‘; #not操作符,否定跟在其後的條件,等價於:where vend_id <>‘DLL01‘

where prod_name like ‘Fish%‘; #like操作符+%通配符,返回所有以Fish起頭的產品

where prod_name like‘%bean bag%‘; #檢索包含文本bean bag的值,不管在之前還是之後。

where prod_name like‘F%y‘; #檢索以F起頭,以y結尾的所有產品

五、匯總數據
select avg(prod_price) as avg_price #avg()用於求均值,只用於單列,忽略列值為null的行
from products;

select count(*) as num_cust from customers; #計算表中行的數目,不忽略空值

select count(cust_email) as num_cust #計算指定列中具有值的行數,掠過空值
from customers;

select max(prod_price) as max_price #返回最大價格,忽略空值
from products;

select min(prod_price) as min_price #返回最低價格,忽略空值
from products;

select sum(quantity) as items_ordered #求和,忽略空值
from orderitems;

六、分組數據
select vend_id,count(*) as num_prods
from products
group by vend_id; #按id進行分組,count對每個id都做一次計數,group by子句必須出現在where子句之後,order by之前

group by cust_id
having count(*)>=2;#過濾分組

七、子查詢
select cust_id from orders
where order_num in(select order_num from orderitems
where prod_id=‘RGAN01‘); #由內向外執行
等價於:
select order_num from orderitems
where prod_id=‘RGAN01‘;

輸出:
order_num
-------------
20007
20008

select cust_id from orders
where order_num in(20007,20008);

八、聯結表
#內連接(等值連接)
select vend_name,prod_name,prod_price
from vendors inner join products
on vendors.vend_id=products.vend_id; #連接條件為vendors.vend_id=products.vend_id
等價於:
select vend_name,prod_name,prod_price
from vendors,products
where vendors.vend_id=products.vend_id;

#多表連接
select prod_name,vend_name,prod_price,quantity
from oederitems,products,vendors
where products.vend_id=vendors.vend_id
and orderitems.prod_id=products.prod_id
and order_num=20007;

#自連接
select c1.cust_id,c1.cust_name,c1.cust_contact
from customers as c1,customers as c2 #使用表別名
where c1.cust_name=c2.cust_name
and c2.cust_contact=‘jim jones‘;
等價於:
select cust_id,cust_name,cust_contact
from customers
where cust_name=(select cust_name
from customers
where cust_contact=‘jim jones‘);

#外連接
select customers.cust_id,orders.order_num
from customers left outer join orders
on customers.cust_id=orders.cust_id; #左外連接,left指定from子句左邊的表(customers)選擇所有行
輸出:

技術分享圖片

select customers.cust_id,orders.order_num
from customers right outer join orders
on customers.cust_id=orders.cust_id; #右外連接,right指定from子句右邊的表(orders)選擇所有行
輸出:

技術分享圖片

九、組合查詢
#union:組合多個查詢的結果到一個輸出集,所以要求union中每個查詢必須包含相同的列,表達式或聚合函數

select cust_name,cust_contact,cust_email
from customers
where cust_state in(‘il‘,‘in‘,‘mi‘);#查詢一
輸出

技術分享圖片

select cust_name,cust_contact,cust_email
from customers
where cust_name=‘fun4all‘;#查詢二
輸出:

技術分享圖片

select cust_name,cust_contact,cust_email
from customers
where cust_state in(‘il‘,‘in‘,‘mi‘)
union
select cust_name,cust_contact,cust_email
from customers
where cust_name=‘fun4all‘; #組合查詢,默認去除重復行,使用union all則返回所有匹配行
輸出

技術分享圖片

十、更新和刪除數據
#update
update customers #指定要更新的表
set cust_email=‘[email protected]‘ #指定列名和其新值
where cust_id=‘1000000005‘; #確定要更新哪些行的過濾條件

update customers
set cust_contact=‘sam roberts‘,
cust_email=‘[email protected]
where cust_id=‘1000000006‘; #更新多個列時,中間用,隔開

update customers
set cust_email=null
where cust_id=‘1000000005‘; #相當於刪除作用

#delete
delete from customers
where cust_id=‘1000000006‘;

SQL經典練習

/*--------------創建並使用數據庫------------*/
mysql> create database 50q;
mysql> use 50q;

/*-------------------建表-------------------------*/
mysql> CREATE TABLE STUDENT
(
SNO VARCHAR(3) NOT NULL,
SNAME VARCHAR(4) NOT NULL,
SSEX VARCHAR(2) NOT NULL,
SBIRTHDAY DATETIME,
CLASS VARCHAR(5)
);

mysql> CREATE TABLE COURSE
(
CNO VARCHAR(5) NOT NULL,
CNAME VARCHAR(10) NOT NULL,
TNO VARCHAR(3) NOT NULL
);

mysql> CREATE TABLE SCORE
(
SNO VARCHAR(3) NOT NULL,
CNO VARCHAR(5) NOT NULL,
DEGREE NUMERIC(10, 1) NOT NULL
) ;

mysql> CREATE TABLE TEACHER
(
TNO VARCHAR(3) NOT NULL,
TNAME VARCHAR(4) NOT NULL,
TSEX VARCHAR(2) NOT NULL,
TBIRTHDAY DATETIME NOT NULL,
PROF VARCHAR(6),
DEPART VARCHAR(10) NOT NULL
);

/*---------------添加主鍵--------------*/
mysql> ALTER TABLE STUDENT ADD PRIMARY KEY (SNO);
ALTER TABLE SCORE ADD PRIMARY KEY (SNO,CNO);
ALTER TABLE COURSE ADD PRIMARY KEY (CNO);
ALTER TABLE TEACHER ADD PRIMARY KEY (TNO);

#--------主鍵在兩張table中的數據類型須一致-------*/

mysql> ALTER TABLE SCORE ADD CONSTRAINT FK_SCORE_STUDENT FOREIGN KEY (SNO) REFERENCES STUDENT(SNO);
ALTER TABLE SCORE ADD CONSTRAINT FK_SCORE_COURSE FOREIGN KEY (CNO) REFERENCES COURSE(CNO);
ALTER TABLE COURSE ADD CONSTRAINT FK_COURSE_TEACHER FOREIGN KEY (TNO) REFERENCES TEACHER(TNO);

/*---------------輸入記錄-------------------*/

mysql-> INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS)
VALUES (108 ,‘曾華‘ ,‘男‘ ,‘1977-09-01‘,95033),
(105 ,‘匡明‘ ,‘男‘ ,‘1975-10-02‘,95031),
(107 ,‘王麗‘ ,‘女‘ ,‘1976-01-23‘,95033),
(101 ,‘李軍‘ ,‘男‘ ,‘1976-02-20‘,95033),
(109 ,‘王芳‘ ,‘女‘ ,‘1975-02-10‘,95031),
(103 ,‘陸君‘ ,‘男‘ ,‘1974-06-03‘,95031);

mysql> INSERT INTO TEACHER(TNO,TNAME,TSEX,TBIRTHDAY,PROF,DEPART)
VALUES (804,‘李誠‘,‘男‘,‘1958-12-02‘,‘副教授‘,‘計算機系‘),
(856,‘張旭‘,‘男‘,‘1969-03-12‘,‘講師‘,‘電子工程系‘),
(825,‘王萍‘,‘女‘,‘1972-05-05‘,‘助教‘,‘計算機系‘),
(831,‘劉冰‘,‘女‘,‘1977-08-14‘,‘助教‘,‘電子工程系‘);

mysql> INSERT INTO COURSE(CNO,CNAME,TNO)
VALUES (‘3-105‘ ,‘計算機導論‘,825),
(‘3-245‘ ,‘操作系統‘ ,804),
(‘6-166‘ ,‘數據電路‘ ,856),
(‘9-888‘ ,‘高等數學‘ ,831);

mysql> INSERT INTO SCORE(SNO,CNO,DEGREE)
VALUES (103,‘3-245‘,86),(105,‘3-245‘,75),
(109,‘3-245‘,68),(103,‘3-105‘,92),
(105,‘3-105‘,88),(109,‘3-105‘,76),
(101,‘3-105‘,64),(107,‘3-105‘,91),
(108,‘3-105‘,78),(101,‘6-166‘,85),
(107,‘6-166‘,79),(108,‘6-166‘,81);

#1.查詢student表中的所有記錄的sname,ssex,class列

-> select sname,ssex,class from student;

#2.查詢教師所有的單位即不重復的Depart列
-> select distinct depart from teacher;

#3.查詢Student表的所有記錄
-> select*from student;

#4.查詢Score表中成績在60到80之間的所有記錄
1)
-> select * from score
-> where degree>=60 and degree<=80;
2)
-> select * from score
-> where degree between 60 and 80;

#5.查詢Score表中成績為85,86或88的記錄
#1)
-> select * from score
-> where degree=85 or degree=86 or degree=88;
#2)
-> select * from score
-> where degree in(85,86,88);

#6.查詢Student表中“95031”班或性別為“女”的同學記錄
-> select * from student
-> where class="95031" or ssex=‘女‘;

#7.以Class降序查詢Student表的所有記錄
-> select * from student
-> order by class desc;

#8.以Cno升序、Degree降序查詢Score表的所有記錄
-> select * from score
-> order by cno,degree desc;

#9.查詢“95031”班的學生人數
-> select count(*) from student
-> where class="95031";

#10.查詢Score表中的最高分的學生學號和課程號
#1)
-> select sno,cno from score
-> where degree=(select max(degree) from score);
#2)
-> select sno, cno from score
-> order by degree desc
-> limit 1;

#11.查詢‘3-105’號課程的平均分
-> select avg(degree) from score
-> where cno=‘3-105‘;

#12.查詢Score表中至少有5名學生選修的並以3開頭的課程的平均分數
-> select avg(degree) from score
-> where cno like‘3%‘
-> group by cno
-> having count(*)>=5;

#13.查詢最低分大於70,最高分小於90的Sno列
mysql> select sno from score
-> group by sno
-> having max(degree)<90 and min(degree)>70;

#14.查詢所有學生的Sname、Cno和Degree列
#1)
-> select sname,cno,degree
-> from student,score
-> where student.sno=score.sno;
#2)
-> select sname,cno,degree
-> from student inner join score
-> on student.sno=score.sno;

#15.查詢所有學生的Sname、Cname和Degree列
-> select sname,cname,degree
-> from student,course,score
-> where student.sno=score.sno
-> and course.cno=score.cno;

#16.查詢“95033”班所選課程的平均分
-> select avg(degree)
-> from score,student
-> where score.sno=student.sno
-> and class="95033";

#17.查詢選修“3-105”課程的成績高於“109”號同學成績的所有同學的記錄
-> select * from score
-> where cno=‘3-105‘ and degree>(select degree from score
-> where cno=‘3-105‘ and sno=109);

#19、查詢score中選學一門以上課程的同學中分數為非最高分成績的記錄
-> select*from score
-> where degree<(select max(degree) from score)
-> and sno in(select sno from score
-> group by sno
-> having count(*)>1);

#20.查詢成績高於學號為“109”、課程號為“3-105”的成績的所有記錄
-> select*from score
-> where degree>(select degree from score
-> where sno=‘109‘
-> and cno=‘3-105‘);

#21、查詢和學號為108的同學同年出生的所有學生的Sno、Sname和Sbirthday列
-> select sno,sname,sbirthday
-> from student
-> where year(sbirthday)=(select year(sbirthday) from student
-> where sno=108);

#22、查詢“張旭“教師任課的學生成績
-> select degree
-> from score,teacher,course
-> where score.cno=course.cno
-> and course.tno=teacher.tno
-> and teacher.tname=‘張旭‘;

#23、查詢選修某課程的同學人數多於5人的教師姓名
-> select tname
-> from teacher,course,score
-> where teacher.tno=course.tno
-> and course.cno=score.cno
-> group by score.cno
-> having count(*)>5;

# 24、查詢95033班和95031班全體學生的記錄
-> select*from student
-> where class in(95033,95031);

#25、查詢出“計算機系“教師所教課程的成績表
-> select degree from score,teacher,course
-> where score.cno=course.cno
-> and course.tno=teacher.tno
-> and teacher.depart=‘計算機系‘;

#26.查詢“計算機系”與“電子工程系“不同職稱的教師的Tname和Prof
-> select tname,prof from teacher
-> where depart=‘計算機系‘
-> and prof not in(select prof from teacher
-> where depart=‘電子工程系‘);

#27、查詢選修編號為“3-105“課程且成績至少高於選修編號為“3-245”的同學的Cno、Sno和Degree,並按Degree從高到低次序排序。
mysql> select*from score
-> where degree>any(select degree from score where cno=‘3-245‘)
-> and cno=‘3-105‘
-> order by degree desc;

#28、查詢選修編號為“3-105”且成績高於選修編號為“3-245”課程的同學的Cno、Sno和Degree.
-> select*from score
-> where degree>all(select degree from score where cno=‘3-245‘)
-> and cno=‘3-105‘;

#29、查詢所有教師和同學的name、sex和birthday
-> select sname as name,ssex as sex,sbirthday as birthday
-> from student
-> union
-> select tname as name,tsex as sex,tbirthday as birthday
-> from teacher;

#30、查詢所有“女”教師和“女”同學的name、sex和birthday
-> select sname as name,ssex as sex,sbirthday as birthday
-> from student
-> where ssex=‘女‘
-> union
-> select tname as name,tsex as sex,tbirthday as birthday
-> from teacher
-> where tsex=‘女‘;

#32、查詢成績比該課程平均成績低的同學的成績表
-> select A.* from score as A
-> where degree<(select avg(degree) from score as B
-> where A.cno=B.cno);

#33、查詢所有任課教師的Tname和Depart
#1)
-> select tname,depart
-> from teacher,course
-> where teacher.tno=course.tno;
#2)
-> select tname,depart from teacher
-> where tno in (select tno from course);
#3)
-> select A.tname,A.depart
-> from teacher A inner join course B
-> on A.tno=B.tno;
#4)
-> select tname,depart from teacher as A
-> where exists(select*from course as B
-> where A.tno=B.tno);#存在則輸出

#34.查詢所有未講課的教師的Tname和Depart
-> select tname,depart from teacher
-> where tno not in(select tno from course);

#35.查詢至少有2名男生的班號
#1)
-> select class from student
-> group by class,ssex
-> having count(*)>=2;
#2)
-> select class from student
-> where ssex=‘男‘
-> group by class;

#36、查詢Student表中不姓“王”的同學記錄
-> select*from student
-> where sname not like ‘王%‘;
-> select sname,year(now())-year(sbirthday) as age
-> from student;#38、查詢Student表中每個學生的姓名和年齡

#37、查詢“男”教師及其所上的課程
-> select teacher.tno,tname,cno
-> from teacher inner join course
-> on teacher.tno=course.tno
-> where tsex=‘男‘;

#38、查詢和“李軍”同性別並同班的同學Sname
-> select A.sname
-> from student as A,student as B
-> where A.ssex=B.ssex
-> and A.class=B.class
-> and B.sname=‘李軍‘;

MySQL基本語句與經典習題