数据库常见面试题集锦,数据库面试题,数据库练习题

建表:
DEPARTMENTS:
DEPARTMENT_ID(primary key),
DEPARTMENT_NAME,
LOCATION

EMPLOYEES:
EMPLOYEE_ID(primary key),
EMPLOYEE_NAME,
EMPLOYEE_JOB,
MANAGER,
SALARY,
DEPARTMENT_ID


1. 列出EMPLOYEES表中各部门的部门号,最高工资,最低工资

select max(SALARY) as 最高工资,min(SALARY) as 最低工资,DEPARTMENT_ID from EMPLOYEES group by DEPARTMENT_ID;

 

2.列出EMPLOYEES表中各部门EMPLOYEE_JOB为'CLERK'的员工的最低工资,最高工资

select max(SALARY) as 最高工资,min(SALARY) as 最低工资,DEPARTMENT_ID as 部门号 from EMPLOYEES where EMPLOYEE_JOB = 'CLERK'
 group by DEPARTMENT_ID;

 

3.对于EMPLOYEES中最低工资小于1000的部门,列出EMPLOYEE_JOB为'CLERK'的员工的部门号,最低工资,最高工资

select max(SALARY) as 最高工资,min(SALARY) as 最低工资,DEPARTMENT_ID as 部门号 from EMPLOYEES as b
where EMPLOYEE_JOB ='CLERK' and 1000>(select min(SALARY) from EMPLOYEES as a 
where a.DEPARTMENT_ID = b.DEPARTMENT_ID) group by b.DEPARTMENT_ID

4.根据部门号由高而低,工资有低而高列出每个员工的姓名,部门号,工资

select DEPARTMENT_ID as 部门号,EMPLOYEE_NAME as 姓名,SALARY as 工资 from EMPLOYEES 
order by DEPARTMENT_ID desc,SALARY asc

5.列出'张三'所在部门中每个员工的姓名与部门号

select EMPLOYEE_NAME,DEPARTMENT_ID from EMPLOYEES where DEPARTMENT_ID = 
(select DEPARTMENT_ID from EMPLOYEES where EMPLOYEE_NAME = '张三')

6.列出每个员工的姓名,工作,部门号,部门名

select EMPLOYEE_NAME,EMPLOYEE_JOB,EMPLOYEES.DEPARTMENT_ID,DEPARTMENTS.DEPARTMENT_NAME 
from EMPLOYEES,DEPARTMENTS where EMPLOYEES.DEPARTMENT_ID = DEPARTMENTS.DEPARTMENT_ID

7.列出EMPLOYEES中工作为'CLERK'的员工的姓名,工作,部门号,部门名

select EMPLOYEE_NAME,EMPLOYEE_JOB,DEPARTMENTS.DEPARTMENT_ID,DEPARTMENT_NAME 
from EMPLOYEES,DEPARTMENTS where DEPARTMENTS.DEPARTMENT_ID = EMPLOYEES.DEPARTMENT_ID and DEPARTMENT_JOB = 'CLERK'

8.对于EMPLOYEES中有管理者的员工,列出姓名,管理者姓名(管理者外键为MANAGER)

select a.EMPLOYEE_NAME as 姓名,b.EMPLOYEE_NAME as 管理者 from EMPLOYEES as a,EMPLOYEES as b 
where a.MANAGER is not null and a.MANAGER = b.EMPLOYEE_ID

9.对于DEPARTMENTS表中,列出所有部门名,部门号,同时列出各部门工作为'CLERK'的员工名与工作

select DEPARTMENT_NAME as 部门名,DEPARTMENTS.DEPARTMENT_ID as 部门号,EMPLOYEE_NAME as 员工名,EMPLOYEE_JOB as 工作 
from DEPARTMENTS,EMPLOYEES where DEPARTMENTS.DEPARTMENT_ID *= EMPLOYEES.DEPARTMENT_ID and EMPLOYEE_JOB = 'CLERK'

10.对于工资高于本部门平均水平的员工,列出部门号,姓名,工资,按部门号排序

select a.DEPARTMENT_ID as 部门号,a.EMPLOYEE_NAME as 姓名,a.SALARY as 工资 from EMPLOYEES as a
where a.SALARY>(select avg(SALARY) from EMPLOYEES as b where a.DEPARTMENT_ID = b.DEPARTMENT_ID) order by a.DEPARTMENT_ID

11.对于EMPLOYEES,列出各个部门中平均工资高于本部门平均水平的员工数和部门号,按部门号排序

select count(a.SALARY) as 员工数,a.DEPARTMENT_ID as 部门号 from EMPLOYEES as a
where a.SALARY>(select avg(SALARY) from EMPLOYEES as b where a.DEPARTMENT_ID = b.DEPARTMENT_ID) 
group by a.DEPARTMENT_ID order by a.DEPARTMENT_ID

12.对于EMPLOYEES中工资高于本部门平均水平,人数多与1人的,列出部门号,人数,按部门号排序

select count(a.EMPLOYEE_ID) as 员工数,a.DEPARTMENT_ID as 部门号,avg(SALARY) as 平均工资 from EMPLOYEES as a
where (select count(c.EMPLOYEE_ID) from EMPLOYEES as c where c.DEPARTMENT_ID = a.DEPARTMENT_ID 
and c.SALARY>(select avg(SALARY) from EMPLOYEES as b where c.DEPARTMENT_ID = b.DEPARTMENT_ID))>1 group by a.DEPARTMENT_ID order by a.DEPARTMENT_ID

13. 对于EMPLOYEES中低于自己工资至少5人的员工,列出其部门号,姓名,工资,以及工资少于自己的人数

select a.DEPARTMENT_ID,a.EMPLOYEE_NAME,a.SALARY,(select count(b.EMPLOYEE_NAME) from EMPLOYEES as b
where b.SALARY < a.SALARY) as 人数 from EMPLOYEES as a where (select count(b.EMPLOYEE_NAME) from EMPLOYEES as b where b.SALARY<a.SALARY)>5

 

三、SQL基础题( 共30分)
设教学数据库Education有三个关系:
学生关系S(SNO,SNAME,AGE,SEX,SDEPT);学习关系SC(SNO,CNO,GRADE);课程关系C(CNO,CNAME,CDEPT,TNAME)
查询问题:
(1)检索计算机系的全体学生的学号,姓名和性别;  3分
(2)检索学习课程号为C2的学生学号与姓名;       3分
(3)检索选修课程名为“DS”的学生学号与姓名;    3分
(4)检索选修课程号为C2或C4的学生学号;        3分
(5)检索至少选修课程号为C2和C4的学生学号;    3分
(6)检索不学C2课的学生姓名和年龄;				5分
(7)检索学习全部课程的学生姓名;			       5分
(8)查询所学课程包含学生S3所学课程的学生学号。 5分

(1)检索计算机系的全体学生的学号,姓名和性别;
SELECT Sno,Sname,Sex 
FROM S
WHERE  Sdept =’CS’;

(2)检索学习课程号为C2的学生学号与姓名;
1.SELECT  Sno,Sname FROM  S WHERE Sno  IN ( SELECT  Sno FROM  SC WHERE Cno=‘C2’)
2.SELECT  S.Sno,Sname FROM S,SC WHERE S.Sno=SC.Sno  AND    SC.Cno=‘C2’;

 (3)检索选修课程名为“DS”的学生学号与姓名
    本查询涉及到学号、姓名和课程名三个属性,分别存放在S和C表中,但S和C表没有直接联系,必须通过SC表建立它们二者的联系。 C →  SC → S
基本思路:
(1)首先在C表中找出“DS”课程的课程号Cno;
(2)然后在SC表中找出Cno等于第一步给出的Cno 集合中的某个元素Cno;
(3)最后在S关系中选出Sno等于第二步中Sno 集合中某个元素的元组,取出Sno 和Sname送入结果表列。
SELECT Sno,Sname 
FROM S
WHERE  Sno  IN(SELECT Sno FROM SC WHERE Cno  IN (SELECT Cno FROM C WHERE  Cname=‘DS’));


(4)检索选修课程号为C2或C4的学生学号;
SELECT  Sno
FROM SC
WHERE  Cno=‘C2’  OR Cno=‘C4’;


(5)检索至少选修课程号为C2和C4的学生学号;
SELECT  Sno
FROM SC  X,SC  Y
WHERE  X.Sno=Y.Sno  AND  X.Cno=‘C2’ AND Y.Cno=‘C4’ ;

(6)检索不学C2课的学生姓名和年龄;
A.SELECT  Sname   FROM  S WHERE Sno  NOT IN ( SELECT  Sn    FROM  SC WHERE Cno=‘C2’);
或者
B.SELECT  Sname FROM  S WHERE  NOT EXISTS ( SELECT  * FROM  SC WHERE SC.Sno=S.Sno AND  Cno=‘C2’);

(7)检索学习全部课程的学生姓名;
在表S中找学生,要求这个学生学了全部课程。换言之,在S表中找学生,在C中不存在一门课程,这个学生没有学。
SELECT Sname 
FROM  S 
WHERE  NOT EXISTS
 (SELECT *
     FROM C)

 

 

CREATE TABLE STUDENT 
(SNO VARCHAR(3) NOT NULL, 
SNAME VARCHAR(4) NOT NULL, 
SSEX VARCHAR(2) NOT NULL, 
SBIRTHDAY DATETIME, 
CLASS VARCHAR(5)) 
go 
CREATE TABLE COURSE 
(CNO VARCHAR(5) NOT NULL, 
CNAME VARCHAR(10) NOT NULL, 
TNO VARCHAR(10) NOT NULL) 
go 
CREATE TABLE SCORE 
(SNO VARCHAR(3) NOT NULL, 
CNO VARCHAR(5) NOT NULL, 
DEGREE NUMERIC(10, 1) NOT NULL) 
go 
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) 

INSERT INTO STUDENT (SNO,SNAME,SSEX,SBIRTHDAY,CLASS) VALUES (103 ,'陆君' ,'男' ,1974-06-03,95031);

1、 查询Student表中的所有记录的Sname、Ssex和Class列。 
2、 查询教师所有的单位即不重复的Depart列。 
3、 查询Student表的所有记录。 
4、 查询Score表中成绩在60到80之间的所有记录。 
5、 查询Score表中成绩为85,86或88的记录。 
6、 查询Student表中“95031”班或性别为“女”的同学记录。 
7、 以Class降序查询Student表的所有记录。 
8、 以Cno升序、Degree降序查询Score表的所有记录。 
9、 查询“95031”班的学生人数。 
10、查询Score表中的最高分的学生学号和课程号。 
11、查询‘3-105’号课程的平均分。 
12、查询Score表中至少有5名学生选修的并以3开头的课程的平均分数。 
13、查询最低分大于70,最高分小于90的Sno列。 
14、查询所有学生的Sname、Cno和Degree列。 
15、查询所有学生的Sno、Cname和Degree列。 
16、查询所有学生的 Sname、Cname和Degree列。 
17、查询“95033”班所选课程的平均分。 
18、假设使用如下命令建立了一个grade 表: 
create table grade(low number(3,0),upp number(3),rank char(1)); 
insert into grade values(90,100,'A'); 
insert into grade values(80,89,'B'); 
insert into grade values(70,79,'C'); 
insert into grade values(60,69,'D'); 
insert into grade values(0,59,'E'); 
现查询所有同学的Sno、Cno和rank列。 
19、查询选修“3-105”课程的成绩高于“109”号同学成绩的所有同学的记录。 
20、查询score中选学一门以上课程的同学中分数为非最高分成绩的记录。 
21、查询成绩高于学号为“109”、课程号为“3-105”的成绩的所有记录。 
22、查询和学号为108的同学同年出生的所有学生的Sno、Sname和Sbirthday列。 
23、查询“张旭“教师任课的学生成绩。 
24、查询选修某课程的同学人数多于5人的教师姓名。 
25、查询95033班和95031班全体学生的记录。 
26、查询存在有85分以上成绩的课程Cno. 
27、查询出 “计算机系“教师所教课程的成绩表。 
28、查询“计算机系”与“电子工程系“不同职称的教师的Tname和Prof。 
29、查询选修编号为“3-105“课程且成绩至少高于选修编号为“3-245”的同学的Cno、Sno和Degree,并按Degree从高到低次序排序。 
30、查询选修编号为“3-105”且成绩高于选修编号为“3-245”课程的同学的Cno、Sno和Degree. 
31、查询所有教师和同学的 name、sex和birthday. 
32、查询所有“女”教师和“女”同学的name、sex和birthday. 
33、查询成绩比该课程平均成绩低的同学的成绩表。 
34、查询所有任课教师的Tname和Depart. 
35 查询所有未讲课的教师的Tname和Depart. 
36、查询至少有2名男生的班号。 
37、查询Student表中不姓“王”的同学记录。 
38、查询Student表中每个学生的姓名和年龄。 
39、查询Student表中最大和最小的Sbirthday日期值。 
40、以班号和年龄从大到小的顺序查询Student表中的全部记录。 
41、查询“男”教师及其所上的课程。 
42、查询最高分同学的Sno、 Cno和Degree列。 
43、查询和“李军”同性别的所有同学的Sname. 
44、查询和“李军”同性别并同班的同学Sname. 
45、查询所有选修“计算机导论”课程的“男”同学的成绩表 

SQL语句练习题参考答案 
1、 select Sname,Ssex,Class from Student; 
2、 select distinct depart from teacher; 
3、 select Sno as '学号',Sname as '姓名',Ssex as '性别',Sbirthday as'出生日期',Class as'班号'from student;
  或 select Sno as 学号,Sname as 姓名,Ssex as 性别,Sbirthday as 出生日期,Class as 班号 from student; 4、 select * from score where degree between 60 and 80; 或select * from score where degree>=60 and degree<=80; 5、 select * from score where degree in (85,86,88); 6、 select * from student where class='95031'or Ssex='女'; 7、 select * from student order by class desc; 8、 select * from score order by cno asc ,degree desc; 或select * from score order by cno ,degree desc; 9、 select count(*) as CNT from student where class='95031'; 10、select Sno as '学号',cno as '课程号', degree as '最高分' from score where degree=(select max(degree) from score) 11、select avg(degree)as 课程平均分 from score where cno='3-105'; 12、 select cno,avg(degree) from score where cno like'3%'group by cno having count(*) >5; 13、select Sno from score group by Sno having min(degree)>70 and max(degree)<90; 14、select student.Sname,score.Cno,score.degree from student,score where student.Sno=score.Sno group by sno; 15、select x.Sno,y.Cname,x.degree from score x,course y where x.Cno=y.Cno; 16、select x.Sname,y.Cname,z.degree from student x,course y,score z where x.Sno=z.Sno and z.Cno=y.Cno; 17、 select y.cno,avg(y.degree) from student x,score y where x.sno=y.sno and x.class='95033'group by y.cno; 18、select Sno,Cno,rank from score,grade where degree between low and upp order by rank; 19、select distinct x.cno,x.sno,x.degree from score x,score y where x.cno = '3-105'
  and x.degree > y.degree and y.sno='109' and y.cno='3-105'; 20、 1,查询成绩非本科最高 select distinct * from score b where degree <(select max(degree) from score a where a.cno=b.cno); 2,查询成绩非本科最高并且选2门以上的学生的成绩: 21、select x.cno,x.sno,x.degree from score x,score y where x.degree > y.degree and y.sno='109'and y.cno='3-105'; select cno,sno,degree from score where degree > (select degree from score where sno='109' and cno='3-105'); 22、 select sno,sname,sbirthday from student where to_char(sbirthday,'yyyy')
    =(select to_char(sbirthday,'yyyy') from student where sno='108'); 23、select cno,sno,degree from score where cno=(select x.cno from course x,teacher y where x.tno=y.tno and y.tname='张旭'); 24、select tname from teacher where tno in(select x.tno from course x,score y where o group by x.tno having count(x.tno)>5); 25、select * from student where class in('95033','95031'); 26、select distinct cno from score where degree in (select degree from score where degree>85); 27、select * from score where cno in(select x.cno from course x,teacher y where y.tno=x.tno and y.depart='计算机系'); 28、select tname,prof from teacher where depart='计算机系' and prof not in (select prof from teacher where depart='电子工程系'); 29、select * from score where cno='3-105' and degree>any (select degree from score where cno='3-245')order by degree desc; 30、select * from score where cno='3-105' and degree>all(select degree from score where cno='3-245'); 31、select tname,tsex,tbirthday from teacher union select sname,ssex,sbirthday from student; 32、select tname,tsex,tbirthday from teacher where tsex='女' union select sname,ssex,sbirthday from student where ssex='女'; 33、select * from score a where degree<(select avg(degree) from score b where a.cno=b.cno); 34、select tname,depart from teacher a where exists (select * from course b where a.tno=b.tno); 35、select tname,depart from teacher a where not exists (select * from course b where a.tno=b.tno); 36、select class from student where ssex='男'group by class having count(*)>=2; 37、select * from student where sname not like'王_'; 38、select sname as 姓名,(to_char(sysdate,'yyyy')-to_char(sbirthday,'yyyy')) as 年龄 from student 39、select sname,sbirthday as 最大 from student where sbirthday =(select min (sbirthday)
  from student)union select sname,sbirthday as 最小 from student where sbirthday =(select max(sbirthday) from student) 40、select class,sname,sbirthday from student order by class desc,sbirthday; 41、select x.tname,y.cname from teacher x,course y where x.tno=y.tno and x.tsex='男'; 42、select * from score where degree=(select max(degree)from score); 43、select sname from student where ssex=(select ssex from student where sname='李军'); 44、select sname from student where ssex=(select ssex from student where sname='李军')
  and class=(select class from student where sname='李军'); 45、select * from score where sno in(select sno from student where ssex='男') and cno=(select cno from course where cname='计算机导论');

 

 

--创建表

USE test

CREATE TABLE emp

    (

      EMPNO NUMERIC(5, 0) NOT NULL ,

      ENAME NVARCHAR(10) ,

      JOB NVARCHAR(9) ,

      MGR NUMERIC(5, 0) ,

      HIREDATE DATETIME ,

      SAL NUMERIC(7, 2) ,

      COMM NUMERIC(7, 2) ,

      DEPTNO NUMERIC(2, 0),

    )

 

CREATE TABLE dept

    (

      DEPTNO NUMERIC(2) ,

      DNAME NVARCHAR(14) ,

      LOC NVARCHAR(13),

    )

 

--插入数据

--1、查询所有的雇员

SELECT  * FROM    emp

--2、查询所有的部门

SELECT  * FROM    dept

--3、查询没有佣金(COMM)的所有雇员信息

SELECT  * FROM    dbo.emp WHERE   COMM IS NULL

--4、查询薪金(SAL)和佣金(COMM)总数大于2000的所有雇员信息

SELECT  * FROM    emp WHERE   ( sal + ISNULL(comm, 0) ) > 2000

--5、选择部门30中的雇员

SELECT * FROM   emp WHERE deptno=30

--6、列出所有办事员("CLERK")的姓名、编号和部门

SELECT  ename ,empno ,dname FROM    emp JOIN dept ON emp.deptno = dept.deptnoWHERE   emp.job = 'CLERK'

--7、找出佣金高于薪金的雇员

SELECT  * FROM    emp WHERE   comm > sal

--8、找出佣金高于薪金60%的雇员

SELECT  * FROM    emp WHERE   comm > sal * 0.6

--9、找出部门10中所有经理和部门20中的所有办事员的详细资料

SELECT  * FROM    emp WHERE   ( job = 'MANAGER' AND deptno = 10) OR ( job = 'CLERK' AND deptno = 20) ORDER BY job

--10、找出部门10中所有经理、部门20中所有办事员,--既不是经理又不是办事员但其薪金>=2000的所有雇员的详细资料

SELECT * FROM   dbo.emp WHERE  ( JOB = 'MANAGER' AND DEPTNO = 10)OR ( JOB = 'CLERK' AND DEPTNO = 20) OR ( JOB NOT IN ( 'MANAGER', 'CLERK' ) AND SAL >= 2000) ORDER BY JOB

--11、找出收取佣金的雇员的不同工作

SELECT DISTINCT JOB FROM   dbo.emp WHERE  COMM IS NOT NULL

--12、找出不收取佣金或收取的佣金低于100的雇员

SELECT * FROM    emp WHERE   ISNULL(comm, 0) < 100

--13、找出早于12年之前受雇的雇员

SELECT  * FROM    dbo.emp WHERE   YEAR(GETDATE()) - YEAR(HIREDATE) > 11

--14、显示首字母大写的所有雇员的姓名

SELECT  ename FROM    emp WHERE   ASCII(ename) BETWEEN 65 AND 90

--15、显示正好为5个字符的雇员姓名

SELECT  ename FROM    emp WHERE   LEN(ename) = 5

--16、显示带有'R'的雇员姓名

SELECT  ENAME FROM    dbo.emp WHERE   ENAME LIKE '%R%''

--17、显示不带有'R'的雇员姓名

SELECT  ENAME FROM    dbo.emp WHERE   ENAME NOT LIKE '%R%'

--18、显示包含"A"的所有雇员的姓名及"A"在姓名字段中的位置

SELECT  ENAME ,CHARINDEX('A', ENAME) A的位置 FROM    dbo.emp WHERE   ENAME LIKE '%A%'

--19、显示所有雇员的姓名,用a替换所有'A'

SELECT  REPLACE(ename, 'A', 'a') ENAME FROM    dbo.emp

--20、显示所有雇员的姓名的前三个字符

SELECT  SUBSTRING(ename, 1, 3) ENAME FROM    dbo.emp

--21、显示雇员的详细资料,按姓名排序

SELECT  * FROM    dbo.emp ORDER BY ENAME

 --22、显示雇员姓名,根据其服务年限,将最老的雇员排在最前面

SELECT  ENAME FROM    dbo.emp ORDER BY HIREDATE

--23、显示所有雇员的姓名、工作和薪金,按工作内的工作的降序顺序排序,

--而工作按薪金排序

SELECT  ename , job ,sal FROM    emp ORDER BY job DESC ,Sal

--24、显示在一个月为30天的情况下所有雇员的日薪金,忽略小数

SELECT  ename 名字 ,CAST(sal / 30 AS NUMERIC) 日薪 FROM    dbo.emp

 --25、找出在(任何年份的)2月受聘的所有雇员

SELECT  ename ,hiredate FROM    dbo.emp WHERE   MONTH(hiredate) = 2

--26、对于每个雇员,显示其加入公司的天数

SELECT  ename 姓名 ,DATEDIFF(DAY, hiredate, GETDATE()) 天数 FROM    dbo.emp

--27、列出至少有一个雇员的所有部门

SELECT  * FROM    dbo.dept WHERE   DEPTNO IN ( SELECT  DEPTNO FROM    dbo.emp )

--28、列出各种类别工作的最低薪金

SELECT  job ,MIN(sal) minsal FROM    dbo.emp GROUP BY job

--29、列出各个部门的MANAGER(经理)的最低薪金

SELECT  ename ,dname ,MIN(sal) minsal FROM    dbo.emp ,dbo.dept WHERE   emp.deptno = dept.deptno AND job = 'MANAGER' GROUP BY dname ,ename

--30、列出薪金高于公司平均水平的所有雇员

SELECT  ename ,sal FROM    dbo.emp WHERE   sal > ( SELECT  AVG(sal)FROM    dbo.emp)

--31、列出各种工作类别的最低薪金,并使最低薪金大于1500

SELECT  job ,MIN(sal) minsal FROM    dbo.emp GROUP BY job HAVING  MIN(sal) > 1500

--32、显示所有雇员的姓名和加入公司的年份和月份,

--按雇员受雇日所在月排序,将最早年份的项目排在最前面

SELECT  ename ,YEAR(hiredate) _year ,MONTH(hiredate) _month FROM    emp ORDER BY hiredate

--33、显示所有雇员的姓名以及满10年服务年限的日期

SELECT  ename ,hiredate FROM    emp WHERE   DATEDIFF(YEAR, hiredate, GETDATE()) > 10

--34、显示所有雇员的服务年限:总的年数或总的月数或总的天数

SELECT  ename ,DATEDIFF(YEAR, hiredate, GETDATE()) _years ,DATEDIFF(MONTH, hiredate, GETDATE()) _months ,DATEDIFF(DAY, hiredate, GETDATE()) _days FROM    dbo.emp

 

--35、列出按计算的字段排序的所有雇员的年薪.

--即:按照年薪对雇员进行排序,年薪指雇员每月的总收入总共12个月的累加

SELECT  ename ,  CAST(sal + ISNULL(comm, 0) AS NUMERIC) * 12 sal_year FROM    dbo.emp

ORDER BY sal_year

--36、列出年薪前5名的雇员

SELECT TOP 5 ename ,CAST(sal + ISNULL(comm, 0) AS NUMERIC) * 12 sal_year FROM    dbo.emp

ORDER BY sal_year DESC

--列出薪金水平处于第四位的雇员

--注意子查询一定要起别名

SELECT  * FROM    ( SELECT    ename ,sal ,rank() OVER ( ORDER BY sal DESC ) AS grade

FROM  emp) AS a WHERE   a.grade = 4

--37、列出年薪低于10000的雇员

SELECT  * FROM    dbo.emp WHERE   ( sal + ISNULL(comm, 0) ) * 12 < 10000

 --38、列出雇员的平均月薪和平均年薪

SELECT  CAST(SUM(sal + ISNULL(comm, 0)) / COUNT(ename) AS NUMERIC) 平均月薪 ,CAST(SUM(( sal + ISNULL(comm, 0) ) * 12) / COUNT(ename) AS NUMERIC) 平均年薪 FROM    emp

--39、列出部门名称和这些部门的雇员,同时列出那些没有雇员的部门(重要)

SELECT  dname ,ename FROM    dept LEFT JOIN emp ON emp.deptno = dept.deptno ORDER BY dname

--列出那些没有雇员的部门

  SELECT  dname FROM    emp RIGHT JOIN dept ON emp.deptno = dept.deptno WHERE   emp.ename IS NULL

--40、列出每个部门的信息以及该部门中雇员的数量(重要)

SELECT  dept.*,COUNT(emp.ENAME) 人数 FROM   dept LEFT JOIN dbo.emp ON dbo.dept.DEPTNO = dbo.emp.DEPTNO GROUP BY dept.DNAME,dept.DEPTNO,dept.LOC ORDER BY dbo.dept.DEPTNO

--41、列出薪金比"SMITH"多的所有雇员

SELECT  emp.ename ,emp.sal FROM  emp WHERE  sal > ( SELECT sal FROM  emp WHERE  ename = 'smith') 

--42、列出所有雇员的姓名及其直接上级的姓名

SELECT  A.ENAME 雇员 ,B.ENAME 直接上级 FROM    dbo.emp A LEFT JOIN dbo.emp B ON A.MGR = B.EMPNO

ORDER BY B.EMPNO

--43、列出入职日期早于其直接上级的所有雇员

SELECT  ename 雇员 ,hiredate 雇员入职日期 FROM    emp e WHERE   hiredate < ( SELECT hiredate

FROM   emp WHERE  empno = e.mgr)

--44、列出所有办事员("CLERK")的姓名及其部门名称

SELECT  ename ,dname ,job FROM    emp e JOIN dept d ON e.deptno = d.deptno WHERE   job = 'CLERK'

--45、列出从事"SALES"(销售)工作的雇员的姓名,假定不知道销售部的部门编号

SELECT  ename FROM    emp WHERE   deptno = ( SELECT   deptno FROM dept WHERE dname = 'sales')

--46、列出与"SCOTT"从事相同工作的所有雇员

SELECT  ename ,job FROM    emp WHERE   job = ( SELECT  job FROM  emp WHERE  ename = 'SCOTT') 

--47、列出某些雇员的姓名和薪金,条件是他们的薪金等于部门30中任何一个雇员的薪金

SELECT  ename ,sal ,deptno FROM   emp WHERE   sal IN ( SELECT sal FROM   emp WHERE  deptno = 30 )

--48、列出某些雇员的姓名和薪金,条件是他们的薪金高于部门30中所有雇员的薪金

SELECT  ename ,sal ,deptno FROM emp WHERE  sal >( SELECT  MAX(sal) FROM  emp WHERE deptno = 30)

--49、列出从事同一种工作但属于不同部门的雇员的不同组合

SELECT  a.ename 雇员A ,b.ename 雇员B ,a.job 雇员A工作 ,  b.job 雇员B工作 ,a.deptno 雇员A部门 ,b.deptno 雇员B部门 FROM    emp a JOIN emp b ON a.job = b.job WHERE   a.deptno != b.deptno

AND a.job = b.job ORDER BY a.job

--50、列出所有雇员的雇员名称、部门名称和薪金(包括没有雇员的部门)

SELECT  dbo.dept.DNAME ,dbo.emp.ENAME ,dbo.emp.SAL FROM    dbo.empRIGHT JOIN dbo.dept ON dbo.dept.DEPTNO = dbo.emp.DEPTNO

 

 

第一方面:

30种mysql优化sql语句查询的方法
1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引。
  2.应尽量避免在 where 子句中使用!=或<>操作符,否则将引擎放弃使用索引而进行全表扫描。
  3.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索引而进行全表扫描,如:
  select id from t where num is null
  可以在num上设置默认值0,确保表中num列没有null值,然后这样查询:
  select id from t where num=0
  4.应尽量避免在 where 子句中使用 or 来连接条件,否则将导致引擎放弃使用索引而进行全表扫描,如:
  select id from t where num=10 or num=20
  可以这样查询:
  select id from t where num=10
  union all
  select id from t where num=20
  5.下面的查询也将导致全表扫描:
  select id from t where name like '%abc%'
  若要提高效率,可以考虑全文检索。
  6.in 和 not in 也要慎用,否则会导致全表扫描,如:
  select id from t where num in(1,2,3)
  对于连续的数值,能用 between 就不要用 in 了:
  select id from t where num between 1 and 3
  7.如果在 where 子句中使用参数,也会导致全表扫描。因为SQL只有在运行时才会解析局部变量,但优化程序不能将访问计划的选择推迟到运行时;它必须在编译时进行选择。然而,如果在编译时建立访问计划,变量的值还是未知的,因而无法作为索引选择的输入项。如下面语句将进行全表扫描:
  select id from t where num=@num
  可以改为强制查询使用索引:
  select id from t with(index(索引名)) where num=@num
  8.应尽量避免在 where 子句中对字段进行表达式操作,这将导致引擎放弃使用索引而进行全表扫描。如:
  select id from t where num/2=100
  应改为:
  select id from t where num=100*2
  9.应尽量避免在where子句中对字段进行函数操作,这将导致引擎放弃使用索引而进行全表扫描。如:
  select id from t where substring(name,1,3)='abc'--name以abc开头的id
  select id from t where datediff(day,createdate,'2005-11-30')=0--'2005-11-30'生成的id
  应改为:
  select id from t where name like 'abc%'
  select id from t where createdate>='2005-11-30' and createdate<'2005-12-1'
  10.不要在 where 子句中的“=”左边进行函数、算术运算或其他表达式运算,否则系统将可能无法正确使用索引。
  11.在使用索引字段作为条件时,如果该索引是复合索引,那么必须使用到该索引中的第一个字段作为条件时才能保证系统使用该索引,否则该索引将不会被使用,并且应尽可能的让字段顺序与索引顺序相一致。
  12.不要写一些没有意义的查询,如需要生成一个空表结构:
  select col1,col2 into #t from t where 1=0
  这类代码不会返回任何结果集,但是会消耗系统资源的,应改成这样:
  create table #t(...)
 
  13.很多时候用 exists 代替 in 是一个好的选择:
  select num from a where num in(select num from b)
  用下面的语句替换:
  select num from a where exists(select 1 from b where num=a.num)
  14.并不是所有索引对查询都有效,SQL是根据表中数据来进行查询优化的,当索引列有大量数据重复时,SQL查询可能不会去利用索引,如一表中有字段sex,male、female几乎各一半,那么即使在sex上建了索引也对查询效率起不了作用。
  15.索引并不是越多越好,索引固然可以提高相应的 select 的效率,但同时也降低了 insert 及 update 的效率,因为 insert 或 update 时有可能会重建索引,所以怎样建索引需要慎重考虑,视具体情况而定。一个表的索引数最好不要超过6个,若太多则应考虑一些不常使用到的列上建的索引是否有必要。
  16.应尽可能的避免更新 clustered 索引数据列,因为 clustered 索引数据列的顺序就是表记录的物理存储顺序,一旦该列值改变将导致整个表记录的顺序的调整,会耗费相当大的资源。若应用系统需要频繁更新 clustered 索引数据列,那么需要考虑是否应将该索引建为 clustered 索引。
  17.尽量使用数字型字段,若只含数值信息的字段尽量不要设计为字符型,这会降低查询和连接的性能,并会增加存储开销。这是因为引擎在处理查询和连接时会逐个比较字符串中每一个字符,而对于数字型而言只需要比较一次就够了。
  18.尽可能的使用 varchar/nvarchar 代替 char/nchar ,因为首先变长字段存储空间小,可以节省存储空间,其次对于查询来说,在一个相对较小的字段内搜索效率显然要高些。
  19.任何地方都不要使用 select * from t ,用具体的字段列表代替“*”,不要返回用不到的任何字段。
  20.尽量使用表变量来代替临时表。如果表变量包含大量数据,请注意索引非常有限(只有主键索引)。
  21.避免频繁创建和删除临时表,以减少系统表资源的消耗。
  22.临时表并不是不可使用,适当地使用它们可以使某些例程更有效,例如,当需要重复引用大型表或常用表中的某个数据集时。但是,对于一次性事件,最好使用导出表。
  23.在新建临时表时,如果一次性插入数据量很大,那么可以使用 select into 代替 create table,避免造成大量 log ,以提高速度;如果数据量不大,为了缓和系统表的资源,应先create table,然后insert。
  24.如果使用到了临时表,在存储过程的最后务必将所有的临时表显式删除,先 truncate table ,然后 drop table ,这样可以避免系统表的较长时间锁定。
  25.尽量避免使用游标,因为游标的效率较差,如果游标操作的数据超过1万行,那么就应该考虑改写。
  26.使用基于游标的方法或临时表方法之前,应先寻找基于集的解决方案来解决问题,基于集的方法通常更有效。
  27.与临时表一样,游标并不是不可使用。对小型数据集使用 FAST_FORWARD 游标通常要优于其他逐行处理方法,尤其是在必须引用几个表才能获得所需的数据时。在结果集中包括“合计”的例程通常要比使用游标执行的速度快。如果开发时间允许,基于游标的方法和基于集的方法都可以尝试一下,看哪一种方法的效果更好。
  28.在所有的存储过程和触发器的开始处设置 SET NOCOUNT ON ,在结束时设置 SET NOCOUNT OFF 。无需在执行存储过程和触发器的每个语句后向客户端发送 DONE_IN_PROC 消息。
  29.尽量避免向客户端返回大数据量,若数据量过大,应该考虑相应需求是否合理。
  30.尽量避免大事务操作,提高系统并发能力。

 

第二方面:
select Count (*)和Select Count(1)以及Select Count(column)区别
一般情况下,Select Count (*)和Select Count(1)两着返回结果是一样的
    假如表沒有主键(Primary key), 那么count(1)比count(*)快,
    如果有主键的話,那主键作为count的条件时候count(主键)最快
    如果你的表只有一个字段的话那count(*)就是最快的
   count(*) 跟 count(1) 的结果一样,都包括对NULL的统计,而count(column) 是不包括NULL的统计

第三方面:
索引列上计算引起的索引失效及优化措施以及注意事项

创建索引、优化查询以便达到更好的查询优化效果。但实际上,MySQL有时并不按我们设计的那样执行查询。MySQL是根据统计信息来生成执行计划的,这就涉及索引及索引的刷选率,表数据量,还有一些额外的因素。
Each table index is queried, and the best index is used unless the optimizer believes that it is more efficient to use a table scan. At one time, a scan was used based on whether the best index spanned more than 30% of the table, but a fixed percentage no longer determines the choice between using an index or a scan. The optimizer now is more complex and bases its estimate on additional factors such as table size, number of rows, and I/O block size.
简而言之,当MYSQL认为符合条件的记录在30%以上,它就不会再使用索引,因为mysql认为走索引的代价比不用索引代价大,所以优化器选择了自己认为代价最小的方式。事实也的确如此

是MYSQL认为记录是30%以上,而不是实际MYSQL去查完再决定的。都查完了,还用什么索引啊?!
MYSQL会先估算,然后决定是否使用索引。

 

转载于:https://www.cnblogs.com/xuchunlin/p/6116302.html

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
sql语句来练习题。1. 写出创建图书表的SQL语句。 Create table book( Book_id char (10) primary key, (主码primary key) Name varchar(30) not null, (非空not null) Author varchar(20) Publish varchar(30) Price decimal(6,2) (,前表示有几位有效数字 ,后表示小数部分有几位) ) 2. 将编号为“NEU1105101”的图书的定价改为50元。 Update book (修改数据update语句) Set price=50 Where book_id=‘NEU1105101’ 3. 查询所有男性读者的姓名和出生日期。 Select name.birthdate From reader Where sex=‘男’ 4. 查询图书表中出现过哪些出版社,每个出版社名称只显示一次,并且按照出版社名称升序排列显示。 Select publish From book Order by publish ASC (按照出版社升序排列显示) 5. 查询借阅过定价介于20元到40元(包括两个边界值)图书的读者的姓名。 Select Name (建立多表连接查询) From borrow join book on borrow.book_id=book.book_id Join reader on borrow.reader_id=reader.readerid Where price >=20 and price <=40 6. 查询每个读者借阅过图书的数量,只显示借阅过图书的读者的读者编号以及借书数量。 Select count(book_id),reader_id (建立多表连接查询) From borrow join book on borrow.book_id=book.book_id Join reader on borrow.reader_id=reader.readerid Group by reder_id 7. 如果有一个名为user001的用户,请写出给他分配对图书表进行数据修改的权限的SQL语句。 Grant update on book to user001 (授权grant语句) 8. 创建一个名为view001的视图,其中包含每个出版社的名称、该出版社出版图书的数量、该出版社出版图书的最高定价、以及该出版社出版图书的最低定价。 Create view view001 (创建视图格式,聚集函数) AS Select publish,count(book_id),MAX(price),MIN(price) From student 9. 显示借阅过书名包含“数据库”字样的女性读者的编号和姓名。 Select Name,reader_id (建立多表连接查询) From borrow join book on borrow.book_id=book.book_id Join reader on borrow.reader_id=reader.readerid Where name like ‘%数据库%’ 10. 显示出版图书数量超过100本的出版社的名称及其出版图书的数量。 Select count(book_id),publish (查询图书数量,出版社名称) From book Group by publish (根据出版社的名称来分组) Having count(book_id)>100 (条件约束) 这里用having 不用where 原因是它不能和聚集函数一起使用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值