Sql經典面試題
第一題: 為管理業務培訓資訊,建立3個表: S(S#,SN,SD,SA)S#,SN,SD,SA分別代表學號,學員姓名,所屬單位,學員年齡 C(C#,CN)C#,CN分別代表課程編號,課程名稱 SC(S#,C#,G) S#,C#,G分別代表學號,所選的課程編號,學習成績 (1)使用標準SQL巢狀語句查詢選修課程名稱為’稅收基礎’的學員學號和姓名? (2) 使用標準SQL巢狀語句查詢選修課程編號為’C2’的學員姓名和所屬單位? (3) 使用標準SQL巢狀語句查詢不選修課程編號為’C5’的學員姓名和所屬單位? (4) 查詢選修了課程的學員人數? (5) 查詢選修課程超過5門的學員學號和所屬單位?
drop table S; drop table C; drop table SC;
create table S ( S# varchar(10), SN varchar (25), SD varchar (25), SA int )
create table C ( C# varchar(10), CN varchar (25) )
create table SC ( S# varchar(10), C# varchar(10), G int Primary Key(S#, C#) )
insert into S values (‘10001’,‘Students1’,‘department1’,23) insert into S values (‘10002’,‘Students2’,‘department1’,24) insert into S values (‘10003’,‘Students3’,‘department2’,25) insert into S values (‘10004’,‘Students4’,‘department2’,26) insert into S values (‘10005’,‘Students5’,‘department3’,23) insert into S values (‘10006’,‘Students6’,‘department3’,24) insert into S values (‘10007’,‘Students7’,‘department3’,25) insert into S values (‘10008’,‘Students8’,‘department4’,25)
insert into C values (‘C1’,‘數學’) insert into C values (‘C2’,‘物理’) insert into C values (‘C3’,‘化學’) insert into C values (‘C4’,‘英語’) insert into C values (‘C5’,‘中文’) insert into C values (‘C6’,‘稅收基礎’) insert into C values (‘C7’,‘傳媒’) insert into C values (‘C8’,‘日語’)
insert into SC values (‘10001’,‘C1’,67) insert into SC values (‘10001’,‘C2’,77) insert into SC values (‘10001’,‘C3’,87) insert into SC values (‘10001’,‘C4’,97) insert into SC values (‘10001’,‘C5’,57) insert into SC values (‘10001’,‘C6’,47)
insert into SC values (‘10002’,‘C1’,62) insert into SC values (‘10002’,‘C2’,72) insert into SC values (‘10002’,‘C3’,82) insert into SC values (‘10002’,‘C4’,92) insert into SC values (‘10002’,‘C5’,52) insert into SC values (‘10002’,‘C6’,42) insert into SC values (‘10004’,‘C2’,74) insert into SC values (‘10004’,‘C5’,54) insert into SC values (‘10004’,‘C6’,44)
–(1)使用標準SQL巢狀語句查詢選修課程名稱為’稅收基礎’的學員學號和姓名?
–解法一: select S#,SN from S where S# in (select S# from C, SC where C.C#=SC.C# and C.CN=‘稅收基礎’) –解法二: select S.S#,S.SN from S inner join (select S# from C left join SC on C.C#=SC.C# where C.CN=‘稅收基礎’) T on T.S#=S.S#
–(2) 使用標準SQL巢狀語句查詢選修課程編號為’C2’的學員姓名和所屬單位?
–解答: select S.SN,S.SD from S,SC where S.S#=SC.S# and SC.C#=‘C2’
–(3) 使用標準SQL巢狀語句查詢不選修課程編號為’C5’的學員姓名和所屬單位?
–解答: select distinct S.SN,S.SD from S where S.S# not in (select S.S# from S,SC where S.S#=SC.S# and SC.C#=‘C5’)
–(4) 查詢選修了課程的學員人數?
–解法一: select 學員人數=count(distinct s#) from sc –解法二: select count(*) as 學員人數 from (select distinct SC.S# from SC) t
–(5) 查詢選修課程超過5門的學員學號和所屬單位?
–解法一: select S#,SD from S where S.S# in (select SC.S# from SC group by SC.S# having count(*)>5) –解法二: select S#,SD from S where S# in(select S# from SC group by S# having count(distinct C#)>5)
第二題: create table testtable1 ( id int IDENTITY, department varchar(12) )
insert into testtable1 values(‘設計’) insert into testtable1 values(‘市場’) insert into testtable1 values(‘售後’)
結果: id department 1 設計 2 市場 3 售後
create table testtable2 ( id int IDENTITY, dptID int, name varchar(12) ) insert into testtable2 values(1,‘張三’) insert into testtable2 values(1,‘李四’) insert into testtable2 values(2,‘王五’) insert into testtable2 values(3,‘彭六’) insert into testtable2 values(4,‘陳七’) insert into testtable2 values(5,‘陳七’)
select t2.id,t2.dptID,t1.department,t2.name from testtable2 t2 left join testtable1 t1 on t1.id=t2.dptID
select * from testtable2
用一條SQL語句,怎麼顯示如下結果 id dptID department name 1 1 設計 張三 2 1 設計 李四 3 2 市場 王五 4 3 售後 彭六 5 4 黑人 陳七
–解答: –解法一: select t2.id,t2.dptID,t1.department,t2.name from testtable2 t2 left join testtable1 t1 on t1.id=t2.dptID –解法二: SELECT t2.id , t2.dptID, ISNULL(t1.department,‘黑人’) dptName,t2.name FROM testtable1 t1 right join testtable2 t2 on t2.dptID = t1.ID
–注意下面兩個語句查詢結果與上面答案的區別 select t2.id,t2.dptID,t1.department,t2.name from testtable1 t1,testtable2 t2 where t1.id=t2.dptID select t2.id,t2.dptID,t1.department,t2.name from testtable2 t2 inner join testtable1 t1 on t1.id=t2.dptID
第三題: 有表A,結構如下: A: p_ID p_Num s_id 1 10 01 1 12 02 2 8 01 3 11 01 3 8 03 其中:p_ID為產品ID,p_Num為產品庫存量,s_id為倉庫ID。請用SQL語句實現將上表中的資料合併,合併後的資料為: p_ID s1_id s2_id s3_id 1 10 12 0 2 8 0 0 3 11 0 8 其中:s1_id為倉庫1的庫存量,s2_id為倉庫2的庫存量,s3_id為倉庫3的庫存量。如果該產品在某倉庫中無庫存量,那麼就是0代替。
create table A ( p_ID int, p_Num int, s_id int )
insert into A values(1,10,01) insert into A values(1,12,02) insert into A values(2,8,01) insert into A values(3,11,01) insert into A values(3,8,03)
–解答: select p_id , sum(case when s_id=1 then p_num else 0 end) as s1_id, sum(case when s_id=2 then p_num else 0 end) as s2_id, sum(case when s_id=3 then p_num else 0 end) as s3_id from A group by p_id
第四題: –1.查詢A(ID,Name)表中第31至40條記錄,ID作為主鍵可能是不是連續增長的列?
create table A ( id int IDENTITY, Name varchar (25) )
–1.查詢A(ID,Name)表中第31至40條記錄,ID作為主鍵可能是不是連續增長的列? –解答: select top 10 * from A where ID >(select max(ID) from (select top 30 ID from A order by id ) T) order by id
第五題: –查詢A(ID,Name)表中存在ID重複三次以上的記 drop table A create table A ( id int, Name varchar (25) )
insert into A values(1,‘a’) insert into A values(2,‘a’) insert into A values(3,‘a’) insert into A values(1,‘a’) insert into A values(2,‘a’) insert into A values(3,‘a’) insert into A values(4,‘a’) insert into A values(1,‘a’) –解答: select id,name from A where id in (select id from A group by id having count(id)>3)order by id
第六題: 原表Course: courseid coursename score
1 java 70 2 oracle 90 3 xml 40 4 jsp 30 5 servlet 80
為了便於閱讀,查詢此表後的結果顯式如下(及格分數為60): courseid coursename score mark
1 java 70 pass 2 oracle 90 pass 3 xml 40 fail 4 jsp 30 fail 5 servlet 80 pass
寫出此查詢語句。
create table Course( courseid int IDENTITY, coursename varchar (25), score int )
insert into Course values ( ‘java’,70) insert into Course values ( ‘oracle’,90) insert into Course values ( ‘xml’,40) insert into Course values ( ‘jsp’,30) insert into Course values ( ‘servlet’,80)
–解答: –oracle: select courseid, coursename ,score ,decode(sign(score-60),-1,‘fail’,‘pass’) as mark from course
–SQL Server: select *, (case when score<60 then ‘failed’ else ‘pass’ end) as mark from Course
第七題: 有表:emp(id, name, age) 要求:列出所有名字重複的人的記錄?
create table emp( id int IDENTITY, name varchar (25), age int )
insert into emp values(‘Zhang1’,26) insert into emp values(‘Zhang2’,27) insert into emp values(‘Zhang3’,28) insert into emp values(‘Zhang1’,26) insert into emp values(‘Zhang2’,27) insert into emp values(‘Zhang3’,29) insert into emp values(‘Zhang1’,26) insert into emp values(‘Zhang2’,27) insert into emp values(‘Zhang3’,28) insert into emp values(‘Zhang1’,26) insert into emp values(‘Zhang4’,22) insert into emp values(‘Wang1’,27) insert into emp values(‘wang2’,28) insert into emp values(‘Wang2’,26) insert into emp values(‘Wang1’,22)
–列出所有名字重複的人的記錄? –解法一:要知道所有名字有重複人資料,首先必須知道哪個名字重複了: select id,name,age from emp where name in (select name from emp group by name having count(*)>1)
–解法二:如果對每個名字都和原表進行比較,大於2個人名字與這條記錄相同的就是合格的 ,就有: select * from emp where (select count(*) from emp e where e.name=emp.name)>1
–解法三:如果有另外一個名字相同的人工號不與她他相同那麼這條記錄符合要求: select * from emp where exists (select * from emp e where e.name=emp.name and e.id<>emp.id) –或: select distinct emp.* from emp inner join emp e on emp.name=e.name and emp.id<>e.id
第八題: 有例表:emp(name,age) Tom 16 Sun 14 Tom 16 Tom 16 要求:過濾掉所有多餘的重複記錄
create table emp( name varchar(20), age int )
insert into emp values(‘Tom’,16) insert into emp values(‘Sun’,14) insert into emp values(‘Tom’,16) insert into emp values(‘Tom’,16)
–解法一:通過distinct、group by過濾重複: select distinct * from emp 或 select name,age from emp group by name,age
–獲得需要的資料,如果可以使用臨時表就有解法: select distinct * into #tmp from emp delete from emp insert into emp select * from #tmp
–但是如果不可以使用臨時表,那該怎麼辦? alter table emp add chk int identity(1,1) –重複記錄可以表示為: select * from emp where (select count() from emp e where e.name=emp.name)>1 –要刪除的是: delete from emp where (select count() from emp e where e.name=emp.name and e.chk>=emp.chk)>1 –再把新增的列刪掉,出現結果。 alter table emp drop column chk
–)另一個思路:檢視 select min(chk) from emp group by name having count(*) >1 –獲得有重複的記錄chk最小的值,於是可以 delete from emp where chk not in (select min(chk) from emp group by name)
第九題:
有列表:emp(emp_no, name,age) 001 Tom 17 002 Sun 14 003 Tom 15 004 Tom 16
要求生成序列號
create table emp( emp_no int, name varchar(20), age int )
insert into emp values(001,‘Tom’,17) insert into emp values(002,‘Sun’,14) insert into emp values(003,‘Tom’,15) insert into emp values(004,‘Tom’,16)
–(1)最簡單的方法:
alter table emp add chk int identity(1,1) –或 select *,identity(int,1,1) chk into #tmp from emp select * from emp alter table emp drop column chk
–如果需要控制順序怎麼辦? select *,identity(int,1,1) chk into #tmp from emp order by age delete from emp alter table emp add chk int insert into emp select * from #tmp select * from #tmp drop table #tmp
–(2)假如不可以更改表結構,怎麼辦?
如果不可以唯一區分每條記錄是沒有辦法的, select emp.,(select count() from emp e where e.emp_no<=emp.emp_no) from emp order by (select count(*) from emp e where e.emp_no<=emp.emp_no)
第十題: 學科表: 姓名 選課
張三 數學 張三 物理 張三 語文 張三 化學
李四 數學 李四 化學 李四 語文
王五 數學 王五 物理 王五 語文
趙六 數學 趙六 物理 趙六 語文
周七 數學 周七 物理
問題一:只選數學,物理,語文的學生, 查詢結果如下,寫出相應SQL語句
姓名 選課
王五 數學 王五 物理 王五 語文
趙六 數學 趙六 物理 趙六 語文
問題二:同時選了數學,物理,語文的學生, 查詢結果如下,寫出相應SQL語句
姓名 選課
張三 數學 張三 物理 張三 語文
王五 數學 王五 物理 王五 語文
趙六 數學 趙六 物理 趙六 語文
create table course( Name varchar(25), CName varchar(25) )
insert into course values (‘張三’,‘數學’) insert into course values (‘張三’,‘物理’) insert into course values (‘張三’,‘語文’) insert into course values (‘張三’,‘化學’)
insert into course values (‘李四’,‘數學’) insert into course values (‘李四’,‘語文’) insert into course values (‘李四’,‘化學’)
insert into course values (‘王五’,‘數學’) insert into course values (‘王五’,‘物理’) insert into course values (‘王五’,‘語文’)
insert into course values (‘趙四’,‘數學’) insert into course values (‘趙四’,‘物理’) insert into course values (‘趙四’,‘語文’)
insert into course values (‘周七’,‘數學’) insert into course values (‘周七’,‘物理’)
select * from course
–問題一:只選數學,物理,語文的學生, 查詢結果如下,寫出相應SQL語句------
–解法一: select A.Name,B.CName from (select T.Name from (select Name,CName from Course where CName in(‘數學’,‘物理’,‘語文’))T group by Name having count()=3 )A, (select Name,CName from Course where CName in(‘數學’,‘物理’,‘語文’))B where A.Name=B.Name and A.Name not in (select Name from Course group by Name having count()>3 ) –解法二: select * from course where name in (select name from course where CName in(‘數學’,‘物理’,‘語文’) group by name having count()=3) and name not in(select name from course group by name having count()>3)
–問題二:同時選了數學,物理,語文的學生, 查詢結果如下,寫出相應SQL語句— –解法一: select A.Name,B.CName from (select T.Name from (select Name,CName from Course where CName in(‘數學’,‘物理’,‘語文’))T group by Name having count(*)=3 )A, (select Name,CName from Course where CName in(‘數學’,‘物理’,‘語文’))B where A.Name=B.Name
–解法二: select * from course where name in (select name from course where CName in(‘數學’,‘物理’,‘語文’) group by name having count(*)=3)
第十一題: 有表students(name,class,grade),請用標準sql語句完成 name class grade 張三 數學 81 李四 語文 70 王五 數學 90 張三 語文 60 李四 數學 100 王五 語文 90 王五 英語 81
要求: 用sql語句輸出各門功課都大於80分的同學姓名?
create table students ( name varchar(25), class varchar(25), grade int )
insert into students values (‘張三’,‘語文’,20) insert into students values (‘張三’,‘數學’,90) insert into students values (‘張三’,‘英語’,50)
insert into students values (‘李四’,‘語文’,81) insert into students values (‘李四’,‘數學’,60) insert into students values (‘李四’,‘英語’,90)
insert into students values (‘王二’,‘數學’,81) insert into students values (‘王二’,‘英語’,90)
insert into students values (‘李五’,‘數學’,83) insert into students values (‘李五’,‘英語’,90) insert into students values (‘李五’,‘化學’,90)
—選出所有成績大於80分的學生姓名----- ------解法一------ select name from students group by name having min(grade)>80
------解法二------ select distinct Name from students where grade >80 and Name not in (select Name from students where grade <80)
------解法三------ select distinct name from students where name not in (select name from students where grade <=80 group by name )
-----解法四------- select name from students group by name having name not in (select name from students where grade<=80)
第十二題: 已知一個表的結構為: 姓名 科目 成績 張三 語文 20 張三 數學 30 張三 英語 50 李四 語文 70 李四 數學 60 李四 英語 90 怎樣通過select語句把他變成以下結構: 姓名 語文 數學 英語 張三 20 30 50 李四 70 60 90
create table students ( name varchar(25), class varchar(25), grade int )
insert into students values (‘張三’,‘語文’,20) insert into students values (‘張三’,‘數學’,90) insert into students values (‘張三’,‘英語’,50)
insert into students values (‘李四’,‘語文’,81) insert into students values (‘李四’,‘數學’,60) insert into students values (‘李四’,‘英語’,90)
–解答: select A.Name,A.grade as 語文,B.grade as 數學,C.grade as 英語 from students A,students B,students C where A.Name=B.Name and B.Name=C.Name and A.class=‘語文’ and B.class=‘數學’ and C.class=‘英語’
第十三題:
我現在有兩張表個表 create table userinfo ( id int, username varchar(32), u_id int ) create table checkinfo ( id int, checktype varchar(32) --出勤的型別(正常,病假,事假) u_id int ) 兩張表通過u_id關聯的 怎麼查詢出每個使用者的某個月出勤的情況: 比如說,1月份,正常出勤多少天,事假多少天,病假多少天? 例如: username 病假(天數) 事假(天數) 病假(天數) 張三 15 5 2
create table userinfo ( id int, username varchar(32), u_id int ) create table checkinfo ( id int, checktype varchar(32), --出勤的型別(正常,病假,事假) u_id int )
delete from userinfo insert into userinfo values(1,‘user1’,1) insert into userinfo values(2,‘user2’,2) insert into userinfo values(3,‘user3’,3) insert into userinfo values(4,‘user4’,4)
insert into checkinfo values(1,‘正常’,1) insert into checkinfo values(2,‘正常’,1) insert into checkinfo values(3,‘病假’,1)
insert into checkinfo values(4,‘正常’,2) insert into checkinfo values(5,‘事假’,2) insert into checkinfo values(6,‘病假’,2) insert into checkinfo values(7,‘正常’,2) insert into checkinfo values(8,‘病假’,2)
insert into checkinfo values(9,‘正常’,3) insert into checkinfo values(10,‘事假’,3) insert into checkinfo values(11,‘病假’,3) insert into checkinfo values(12,‘正常’,3) insert into checkinfo values(13,‘正常’,3) insert into checkinfo values(14,‘正常’,3) insert into checkinfo values(15,‘正常’,3) insert into checkinfo values(16,‘病假’,3)
insert into checkinfo values(17,‘正常’,4) insert into checkinfo values(18,‘事假’,4) insert into checkinfo values(19,‘病假’,4) insert into checkinfo values(20,‘正常’,4) insert into checkinfo values(21,‘事假’,4) insert into checkinfo values(22,‘病假’,4) insert into checkinfo values(23,‘事假’,4) insert into checkinfo values(24,‘病假’,4)
—解法一: select b.*,m.正常,m.事假,m.病假 from userinfo b join (select a.u_id, count(case when a.checktype=‘病假’ then ‘1’ end ) 病假 , count(case when a.checktype=‘正常’ then ‘1’ end ) 正常 , count(case when a.checktype=‘事假’ then ‘1’ end ) 事假 from checkinfo a group by a.u_id) m on m.u_id=b.u_id
—解法二: select b.* ,m1.正常,m2.病假,m3.事假 from userinfo b left join (select a.u_id, count(a.checktype) 正常 from checkinfo a where a.checktype=‘正常’ group by a.u_id ) m1 on b.u_id=m1.u_id left join (select a.u_id, count(a.checktype) 病假 from checkinfo a where a.checktype=‘病假’ group by a.u_id ) m2 on b.u_id=m2.u_id left join (select a.u_id, count(a.checktype) 事假 from checkinfo a where a.checktype=‘事假’ group by a.u_id ) m3 on b.u_id=m3.u_id
第十四題: 產品 顏色 數量 產品1 紅色 100 產品1 藍色 80 產品2 藍色 103 產品2 紅色 NULL 產品2 紅色 89 產品1 紅色 100 1:按產品分類,僅列出各類商品中紅色多於藍色的商品名稱及差額數量
create table products( name varchar(20), color char(20), quantities int )
insert into products values(‘產品1’,‘紅色’,100) insert into products values(‘產品1’,‘藍色’,80)
insert into products values(‘產品2’,‘紅色’,null) insert into products values(‘產品2’,‘藍色’,103) insert into products values(‘產品2’,‘紅色’,89)
insert into products values(‘產品1’,‘紅色’,100)
-----解答: —第一步:查詢出每種商品中蘭色和紅色數量及產品名稱
–紅色: select name,sum(quantities) from products where color=‘紅色’ group by name
–藍色: select name,sum(quantities) from products where color=‘藍色’ group by name
—第二步:查詢出要求的結果: select t1.name,t1.x-t2.x as balance from (select name,sum(quantities) as x from products where color=‘紅色’ group by name) t1, (select name,sum(quantities) as x from products where color=‘藍色’ group by name) t2 where t1.x >t2.x and t1.name=t2.name
第十五題: –查詢學生表中,選修課超過5門的名字! create table students ( id int IDENTITY, name varchar(20), elective_course varchar(20) )
insert into students values(‘student1’,‘course1’) insert into students values(‘student1’,‘course2’) insert into students values(‘student1’,‘course3’) insert into students values(‘student1’,‘course4’) insert into students values(‘student1’,‘course6’) insert into students values(‘student1’,‘course6’)
insert into students values(‘student2’,‘course1’) insert into students values(‘student2’,‘course2’) insert into students values(‘student2’,‘course3’) insert into students values(‘student2’,‘course4’) insert into students values(‘student2’,‘course5’)
insert into students values(‘student3’,‘course1’) insert into students values(‘student3’,‘course2’) insert into students values(‘student3’,‘course3’) insert into students values(‘student3’,‘course4’)
insert into students values(‘student4’,‘course1’) insert into students values(‘student4’,‘course2’) insert into students values(‘student4’,‘course3’) insert into students values(‘student4’,‘course4’) insert into students values(‘student4’,‘course5’) insert into students values(‘student4’,‘course6’) insert into students values(‘student4’,‘course7’)
insert into students values(‘student5’,‘course2’) insert into students values(‘student5’,‘course3’) insert into students values(‘student5’,‘course4’) insert into students values(‘student5’,‘course5’) insert into students values(‘student5’,‘course6’) insert into students values(‘student5’,‘course7’) insert into students values(‘student5’,‘course8’) insert into students values(‘student5’,‘course9’)
insert into students values(‘student6’,‘course7’) insert into students values(‘student6’,‘course8’) insert into students values(‘student6’,‘course9’)
–解答: select name from students group by name having count(elective_course)>=5
第十六題: DbTable表有三列,id,name,data,其中name列裡每行都含有’{data}’,如第一行裡為’aa{data}bb’,第二行為’abc{data}cd’,要求用對應data列的 資料替換掉’{data}’,sql怎麼寫?
create table DbTable ( ID int IDENTITY, name varchar(20), data varchar(10) )
insert into DbTable values (‘a1{data}bb’,‘1’) insert into DbTable values (‘a2{data}bb’,‘2’) insert into DbTable values (‘a3{data}bb’,‘3’) insert into DbTable values (‘a4{data}bb’,‘4’) insert into DbTable values (‘a5{data}bb’,‘5’)
–解答: update DbTable set name=replace(name,’{data}’,data) select * from DbTable
第十七題: 存在表table(FID,FCLASS,FSSCORE),三欄位分別代表姓名、班級、成績。用最高效、最簡單的SQL語句列出人數大於30的各班最高成績的列表,顯示 班級、成績兩個欄位。
create table F3 ( FID varchar(20), FLASS varchar(20), FSSCORE int )
insert into F3 values (‘S_Name1’,‘Class1’,67) insert into F3 values (‘S_Name2’,‘Class1’,57) insert into F3 values (‘S_Name3’,‘Class1’,27) insert into F3 values (‘S_Name4’,‘Class1’,37) insert into F3 values (‘S_Name5’,‘Class1’,97)
insert into F3 values (‘S_Name6’,‘Class2’,67) insert into F3 values (‘S_Name7’,‘Class2’,57) insert into F3 values (‘S_Name8’,‘Class2’,27) insert into F3 values (‘S_Name9’,‘Class2’,37) insert into F3 values (‘S_Name10’,‘Class2’,97) insert into F3 values (‘S_Name11’,‘Class2’,37) insert into F3 values (‘S_Name112’,‘Class2’,97)
insert into F3 values (‘S_Name17’,‘Class3’,57) insert into F3 values (‘S_Name18’,‘Class3’,27) insert into F3 values (‘S_Name19’,‘Class3’,37) insert into F3 values (‘S_Name110’,‘Class3’,88) insert into F3 values (‘S_Name111’,‘Class3’,37) insert into F3 values (‘S_Name1112’,‘Class3’,67)
insert into F3 values (‘S_Name117’,‘Class4’,57) insert into F3 values (‘S_Name118’,‘Class4’,27) insert into F3 values (‘S_Name119’,‘Class4’,37) insert into F3 values (‘S_Name1110’,‘Class4’,82) insert into F3 values (‘S_Name1111’,‘Class4’,37) insert into F3 values (‘S_Name11112’,‘Class4’,67)
insert into F3 values (‘S_Name11111’,‘Class5’,37) insert into F3 values (‘S_Name111112’,‘Class5’,67)
—解答:為了便於組裝測試資料,這裡一以5為人數
–解法一: select F3.FLASS, Max(FSSCORE) from F3 group by FLASS having count(*) >=5
–解法二: –第一步:查詢出人數大於5的班級– select FLASS ,count() as Total from F3 group by FLASS having count() >= 5 –第二步:查詢出所有人數大於5的班級的所有學生記錄– select * from F3 where FLASS in (select FLASS from F3 group by FLASS having count() >= 5 ) –第三步:通過對第二步的記錄根據FCLASS分組查詢– select FLASS, Max(FSSCORE) from F3 where FLASS in (select FLASS from F3 group by FLASS having count() >= 5 ) group by FLASS
–解法三: select FLASS,max(fsscore) from ( select * from F3 where FLASS in (select FLASS from F3 group by FLASS having count(*)>=5) ) T group by FLASS
第十八題: 有一張老師表Teachers,欄位是T_ID,T_NAME;有一張學生表Students,欄位是S_ID,S_NAME;還有一張班級表Classes,欄位是T_ID,S_ID,C_NAME,其中 C_NAME的取值只有‘大班’和‘小班’,請查詢出符合條件的老師的名字,條件是老師在大班中帶的學生數大於此老師在小班中帶的學生數。
create table Teachers ( T_ID int, T_NAME varchar(20) )
create table Students ( S_ID int, S_NAME varchar(20) )
create table Classes ( T_ID int, S_ID int, C_NAME varchar(20) )
insert into Teachers values(1,‘T1’) insert into Teachers values(2,‘T2’) insert into Teachers values(3,‘T3’) insert into Teachers values(4,‘T4’) insert into Teachers values(5,‘T5’)
insert into Students values(1,‘S1’) insert into Students values(2,‘S1’) insert into Students values(3,‘S1’) insert into Students values(4,‘S1’) insert into Students values(5,‘S1’) insert into Students values(6,‘S1’) insert into Students values(7,‘S1’) insert into Students values(8,‘S1’) insert into Students values(9,‘S1’) insert into Students values(10,‘S1’) insert into Students values(11,‘S1’) insert into Students values(12,‘S1’) insert into Students values(13,‘S1’) insert into Students values(14,‘S1’) insert into Students values(15,‘S1’) insert into Students values(16,‘S1’)
insert into Classes values(1,1,‘大班’) insert into Classes values(1,2,‘大班’) insert into Classes values(1,3,‘小班’) insert into Classes values(1,4,‘大班’) insert into Classes values(1,13,‘大班’) insert into Classes values(1,14,‘大班’) insert into Classes values(1,15,‘小班’) insert into Classes values(1,16,‘大班’)
insert into Classes values(2,1,‘大班’) insert into Classes values(2,2,‘小班’) insert into Classes values(2,3,‘大班’) insert into Classes values(2,4,‘大班’) insert into Classes values(2,16,‘小班’) insert into Classes values(2,15,‘小班’) insert into Classes values(2,14,‘小班’)
insert into Classes values(3,5,‘大班’) insert into Classes values(3,6,‘小班’) insert into Classes values(3,7,‘大班’) insert into Classes values(4,4,‘大班’)
insert into Classes values(4,5,‘大班’) insert into Classes values(4,6,‘小班’) insert into Classes values(4,7,‘小班’) insert into Classes values(4,8,‘小班’)
insert into Classes values(5,9,‘大班’) insert into Classes values(5,10,‘小班’) insert into Classes values(5,11,‘小班’) insert into Classes values(5,12,‘小班’)
–第一步:查詢出每個老師所帶的小班的人數-------- select T_ID,count(*) as x from Classes where C_Name=‘小班’ group by T_ID
–第二步:查詢出每個老師所帶的大班的人數-------- select T_ID,count(*) as x from Classes where C_Name=‘大班’ group by T_ID
–第三步:在上面一二步的基礎上查詢出大班人數大於小班人數的老師------------
select T_NAME from Teachers t, (select T_ID,count() as x from Classes where C_Name=‘小班’ group by T_ID) T1, (select T_ID,count() as x from Classes where C_Name=‘大班’ group by T_ID) T2 where T1.x<T2.x and T1.T_ID=T2.T_ID and t.T_ID=T1.T_ID –考察要點:1.分組查詢. 2.把查詢出來的某些結果作為表來連線查詢出相關結果.
第十九題: 前提:a 部門表 b 員工表 a表字段( id --部門編號 departmentName-部門名稱 ) b表字段( id–部門編號 employee- 員工名稱 )
問題:如何一條sql語句查詢出每個部門共有多少人? */ create table departments( ID int IDENTITY, Name varchar (20), )
create table employees( ID int, Name varchar (20) )
insert into departments values (‘DeparmentA’) insert into departments values (‘DeparmentB’) insert into departments values (‘DeparmentC’) insert into departments values (‘DeparmentD’) insert into departments values (‘DeparmentE’)
insert into employees values (1,‘Zhang3’) insert into employees values (1,‘Zhang4’) insert into employees values (1,‘Zhang5’)
insert into employees values (2,‘Li3’) insert into employees values (2,‘Li4’) insert into employees values (2,‘Li5’) insert into employees values (2,‘Li6’)
insert into employees values (3,‘Zhao3’) insert into employees values (3,‘Zhao4’) insert into employees values (3,‘Zhao5’)
insert into employees values (4,‘Chen4’) insert into employees values (4,‘Chen5’)
insert into employees values (5,‘Zhu4’)
–解法一---- select b.id,a.Name,count(b.id)as employeecount from departments a left join employees b on a.id=b.id group by b.id,a.Name —或 select b.id,a.Name,count(*)as employeecount from departments a left join employees b on a.id=b.id group by b.id,a.Name
—解法二— select t.id as ‘Id’, t.name as ‘Name’,count (*) as ‘EmployeeCount’ from (select d.id,d.name from departments as d inner join employees as e on d.id=e.id) t group by t.id,t.name
–解法三---- select a.id,a.Name,count(b.id)as employeecount from departments a left join employees b on a.id=b.id group by a.id,a.Name
第二十題: 在Oracle資料庫中有一張表A 編號 名稱 1 a 2 b 3 c 4 d 如何寫一條SQL語句,顯示以下結果 ab,ac,ad,bc,cd
drop table B select b.id,b.name from B b
create table B ( id int IDENTITY, name varchar (20) )
insert into B values (‘a’) insert into B values (‘b’) insert into B values (‘c’) insert into B values (‘d’)
–Oracle: select distinct a.name||b.name||’,’||a.name||c.name||’,’||a.name||d.name||’,’||b.name||c.name||’,’||c.name||d.name from B a,B b,B c,B d where a.number=1 and b.number=2 and c.number=3 and d.number=4
–其它參考:如果要求你在同一列顯示呢? ab ac ad bc bd cd –參考答案: select a.name+b.name from B a,B b where a.id<b.id group by a.name+b.name 第二十題: 怎麼樣抽取重複記錄 表:
id name
1 test1 2 test2 3 test3 4 test4 5 test5 6 test6 2 test2 3 test3 2 test2 6 test6
查出所有有重複記錄的資料,用一句sql 來實現
create table D( id varchar (20), name varchar (20) )
insert into D values(‘1’,‘test1’) insert into D values(‘2’,‘test2’) insert into D values(‘3’,‘test3’) insert into D values(‘4’,‘test4’) insert into D values(‘6’,‘test6’) insert into D values(‘5’,‘test5’) insert into D values(‘2’,‘test2’) insert into D values(‘3’,‘test3’) insert into D values(‘4’,‘test4’) insert into D values(‘7’,‘test7’) insert into D values(‘4’,‘test4’) insert into D values(‘6’,‘test6’) insert into D values(‘5’,‘test5’) insert into D values(‘2’,‘test2’) insert into D values(‘3’,‘test3’) insert into D values(‘4’,‘test4’) insert into D values(‘8’,‘test8’) insert into D values(‘10’,‘test4’)
select * from D where
–解法一: –查詢出重複的記錄 select id,name from D group by id,name having count()>1 –查詢出重複的記錄及重複次數 select a.id,a.name from D a,(select id,name from D group by id,name having count()>1) b where a.id=b.id and a.name=b.name
–解法二: select t1.* from D t1, (select sum(1) as Sig,id,name from D group by id,name) as t2 where t1.name=t2.name and t1.id=t2.id and t2.Sig>1
第二十一題: 已知原表(t_salary) year salary 2000 1000 2001 2000 2002 3000 2003 4000 先要實現顯示結果(salary為以前的工資和) year salary 2000 1000 2001 3000 請問SQL語句怎麼寫?
create table t_salary( year int, salary int )
select * from t_salary insert into t_salary values(2000,1000) insert into t_salary values(2001,2000) insert into t_salary values(2002,3000) insert into t_salary values(2003,4000)
–解答: select year, (select sum(salary) from t_salary b where b.year <= a.year) salary from t_salary a group by year
第二十二題: year month total 1996 1 3000 1996 3 4000 1996 7 5000 1997 3 4000 1997 6 3000 . 要求按如下格式輸出: year m1,m2,m3,m4 year 為年,m1等為季度,要求按上行輸出
create table Outputs ( year char(4), month int, total int )
insert into Outputs values (‘1996’,1,3000) insert into Outputs values (‘1996’,3,4000) insert into Outputs values (‘1996’,7,5000)
insert into Outputs values (‘1997’,3,4000) insert into Outputs values (‘1997’,6,3000) insert into Outputs values (‘1997’,2,3000)
insert into Outputs values (‘1998’,1,3000) insert into Outputs values (‘1998’,4,3500)
select * from Outputs
----------------解答------------------- –解法一: select year, sum(case when month<=3 then total else 0 end) as M1, sum(case when month>3 and month<=6 then total else 0 end) as M2, sum(case when month>6 and month<=9 then total else 0 end) as M3, sum(case when month>9 and month<=12 then total else 0 end) as M2 from Outputs group by year
–解法二: select year, sum(case when month in(1,2,3) then total else 0 end) as M1, sum(case when month in(4,5,6) then total else 0 end) as M2, sum(case when month in(7,8,9) then total else 0 end) as M3, sum(case when month in(10,11,12) then total else 0 end) as M2 from Outputs group by year
第二十三題:
普通行列轉換 問題:假設有張學生成績表(tb)如下: 姓名 課程 分數 張三 語文 74 張三 數學 83 張三 物理 93 李四 語文 74 李四 數學 84 李四 物理 94 想變成(得到如下結果): 姓名 語文 數學 物理
李四 74 84 94 張三 74 83 93
create table tb( 姓名 varchar(10) , 課程 varchar(10) , 分數 int) insert into tb values(‘張三’ , ‘語文’ , 74) insert into tb values(‘張三’ , ‘數學’ , 83) insert into tb values(‘張三’ , ‘物理’ , 93) insert into tb values(‘李四’ , ‘語文’ , 74) insert into tb values(‘李四’ , ‘數學’ , 84) insert into tb values(‘李四’ , ‘物理’ , 94) insert into tb values(‘李四’ , ‘歷史’ , 94) go
-----解法一:SQL SERVER 2000 靜態SQL,指課程只有語文、數學、物理這三門課程。(以下同)--------- select 姓名, max(case when 課程=‘語文’ then 分數 end) as 語文, max(case when 課程=‘數學’ then 分數 end) as 數學, max(case when 課程=‘物理’ then 分數 end) as 物理 from tb group by 姓名
-----解法二:–SQL SERVER 2000 動態SQL,指課程不止語文、數學、物理這三門課程。(以下同) --------- declare @sql varchar(8000) set @sql = ‘select 姓名 ’ select @sql = @sql + ’ , max(case 課程 when ‘’’ + 課程 + ‘’’ then 分數 else 0 end) [’ + 課程 + ‘]’ from (select distinct 課程 from tb) as a set @sql = @sql + ’ from tb group by 姓名’ exec(@sql)
-----解法三:SQL SERVER 2005 靜態SQL。 select * from (select * from tb) a pivot (max(分數) for 課程 in (語文,數學,物理)) b
-----解法四:SQL SERVER 2005 靜態SQL。 declare @sql varchar(8000) select @sql = isnull(@sql + ‘,’ , ‘’) + 課程 from tb group by 課程 exec (‘select * from (select * from tb) a pivot (max(分數) for 課程 in (’ + @sql + ‘)) b’)
問題:在上述結果的基礎上加平均分,總分,得到如下結果: 姓名 語文 數學 物理 平均分 總分
李四 74 84 94 84.00 252 張三 74 83 93 83.33 250
–SQL SERVER 2000 靜態SQL。 select 姓名 姓名, max(case 課程 when ‘語文’ then 分數 else 0 end) 語文, max(case 課程 when ‘數學’ then 分數 else 0 end) 數學, max(case 課程 when ‘物理’ then 分數 else 0 end) 物理, cast(avg(分數*1.0) as decimal(18,2)) 平均分, sum(分數) 總分 from tb group by 姓名
–SQL SERVER 2000 動態SQL。 declare @sql varchar(8000) set @sql = ‘select 姓名 ’ select @sql = @sql + ’ , max(case 課程 when ‘’’ + 課程 + ‘’’ then 分數 else 0 end) [’ + 課程 + ‘]’ from (select distinct 課程 from tb) as a set @sql = @sql + ’ , cast(avg(分數*1.0) as decimal(18,2)) 平均分 , sum(分數) 總分 from tb group by 姓名’ exec(@sql)
–SQL SERVER 2005 靜態SQL。 select m.* , n.平均分 , n.總分 from (select * from (select * from tb) a pivot (max(分數) for 課程 in (語文,數學,物理)) b) m, (select 姓名 , cast(avg(分數*1.0) as decimal(18,2)) 平均分 , sum(分數) 總分 from tb group by 姓名) n where m.姓名 = n.姓名
–SQL SERVER 2005 動態SQL。 declare @sql varchar(8000) select @sql = isnull(@sql + ‘,’ , ‘’) + 課程 from tb group by 課程 exec (‘select m.* , n.平均分 , n.總分 from (select * from (select * from tb) a pivot (max(分數) for 課程 in (’ + @sql + ‘)) b) m , (select 姓名 , cast(avg(分數*1.0) as decimal(18,2)) 平均分 , sum(分數) 總分 from tb group by 姓名) n where m.姓名 = n.姓名’)
drop table tb
問題:如果上述兩表互相換一下:即表結構和資料為: 姓名 語文 數學 物理 張三 74 83 93 李四 74 84 94 想變成(得到如下結果): 姓名 課程 分數
李四 語文 74 李四 數學 84 李四 物理 94 張三 語文 74 張三 數學 83 張三 物理 93
create table tb(姓名 varchar(10) , 語文 int , 數學 int , 物理 int) insert into tb values(‘張三’,74,83,93) insert into tb values(‘李四’,74,84,94) go
–SQL SERVER 2000 靜態SQL。 select * from ( select 姓名 , 課程 = ‘語文’ , 分數 = 語文 from tb union all select 姓名 , 課程 = ‘數學’ , 分數 = 數學 from tb union all select 姓名 , 課程 = ‘物理’ , 分數 = 物理 from tb ) t order by 姓名 , case 課程 when ‘語文’ then 1 when ‘數學’ then 2 when ‘物理’ then 3 end
–SQL SERVER 2000 動態SQL。 –呼叫系統表動態生態。 declare @sql varchar(8000) select @sql = isnull(@sql + ’ union all ’ , ‘’ ) + ’ select 姓名 , [課程] = ’ + quotename(Name , ‘’’’) + ’ , [分數] = ’ + quotename(Name) + ’ from tb’ from syscolumns where name! = N’姓名’ and ID = object_id(‘tb’) --表名tb,不包含列名為姓名的其它列 order by colid asc exec(@sql + ’ order by 姓名 ')
–SQL SERVER 2005 動態SQL。 select 姓名 , 課程 , 分數 from tb unpivot (分數 for 課程 in([語文] , [數學] , [物理])) t
–SQL SERVER 2005 動態SQL,同SQL SERVER 2000 動態SQL。
問題:在上述的結果上加個平均分,總分,得到如下結果: 姓名 課程 分數
李四 語文 74.00 李四 數學 84.00 李四 物理 94.00 李四 平均分 84.00 李四 總分 252.00 張三 語文 74.00 張三 數學 83.00 張三 物理 93.00 張三 平均分 83.33 張三 總分 250.00
select * from ( select 姓名 as 姓名 , 課程 = ‘語文’ , 分數 = 語文 from tb union all select 姓名 as 姓名 , 課程 = ‘數學’ , 分數 = 數學 from tb union all select 姓名 as 姓名 , 課程 = ‘物理’ , 分數 = 物理 from tb union all select 姓名 as 姓名 , 課程 = ‘平均分’ , 分數 = cast((語文 + 數學 + 物理)*1.0/3 as decimal(18,2)) from tb union all select 姓名 as 姓名 , 課程 = ‘總分’ , 分數 = 語文 + 數學 + 物理 from tb ) t order by 姓名 , case 課程 when ‘語文’ then 1 when ‘數學’ then 2 when ‘物理’ then 3 when ‘平均分’ then 4 when ‘總分’ then 5 end