以下算式,在Oracle 11g中,计算某个年龄段的月平均收入(薪资+津贴),哪一个是正确的查询呢?
AVG(SAL+COMM)
AVG(SAL)
AVG(COMM)
(AVG(SAL)+AVG(COMM))
AVG(SAL+COMM)
SUM(SAL+COMM)
(SUM(SAL)+SUM(COMM))/COUNT(*)
答案是(SUM(SAL)+SUM(COMM))/COUNT(*)
SQL语句练习
a. SCHOOL_INFORMATION(学校基础信息表)
c. TEACHER_ INFORMATION(教师基本信息表)
(3) 目前要统计“树德中学”的职称为“高级教师”的老师数量,写出完整语句。
(4) 目前要查询“石室中学”的职称为“中级教师”职称的男老师姓名,写出完整语句。(假设职称顺序为 实习教师、初级教师、中级教师、高级教师)
(5) 目前要查询本市青年老师(年龄为20-30)岁的月平均收入,写出完整语句。
现有某市的中学教师管理系统设计表如下:
基于Oracle database的SQL语法,完成以下题目:
(1) 定义各表,写出完整语句。
(2) 目前要统计全市中学的男女老师数量,写出完整语句。
(3) 目前要统计“树德中学”的职称为“高级教师”的老师数量,写出完整语句。
(4) 目前要查询“石室中学”的职称为“中级教师”职称的男老师姓名,写出完整语句。(假设职称顺序为 实习教师、初级教师、中级教师、高级教师)
(5) 目前要查询本市青年老师(年龄为20-30)岁的月平均收入,写出完整语句。
回答:
(1) 定义各表,写出完整语句。
a. SCHOOL_INFORMATION(学校基础信息表)
CREATE TABLE SCHOOL_INFORMATION
(
SCHOOLID NUMBER(1,0) NOT NULL,
SCHOOLNAME VARCHAR2(50) NOT NULL,
SCHOOLADDR VARCHAR2(300),
CONSTRAINT SCHOOL_INFORMATION_PK PRIMARY KEY
(
SCHOOLID
)
)
创建之后查看如图:
b. TEACHER_LEVEL(教师职称、工资标准表)
CREATE TABLE TEACHER_LEVEL
(
TLEVELID NUMBER(1,0) NOT NULL,
TFLEVERID NUMBER(1,0),
TLEVELNAME VARCHAR2(50) NOT NULL,
TLEVALSAL NUMBER(6,2) NOT NULL,
TLEVALCOMM NUMBER(6,2) NOT NULL,
CONSTRAINT TEACHER_LEVEL_PK PRIMARY KEY
(
TLEVELID
),
CONSTRAINT TEACHER_LEVEL_TFLEVERID_FK FOREIGN KEY
(
TFLEVERID
) REFERENCES TEACHER_LEVEL(TLEVELID)
)
创建之后查看如图:
c. TEACHER_ INFORMATION(教师基本信息表)
CREATE TABLE TEACHER_INFORMATION
(
TEACHERID NUMBER(4,0) NOT NULL,
SCHOOLID NUMBER(1,0) NOT NULL,
TLEVELID NUMBER(1,0) NOT NULL,
TEACHERNAME VARCHAR2(50) NOT NULL,
TEACHERSEX NUMBER(1,0) NOT NULL,
TEACHERBIRTH DATE NOT NULL,
CONSTRAINT TEACHER_INFORMATION_PK PRIMARY KEY
(
TEACHERID
),
CONSTRAINT T_INFORMATION_SCHOOLID_FK FOREIGN KEY
(
SCHOOLID
) REFERENCES SCHOOL_INFORMATION(SCHOOLID),
CONSTRAINT T_INFORMATION_TLEVELID_FK FOREIGN KEY
(
TLEVELID
) REFERENCES TEACHER_LEVEL(TLEVELID),
CONSTRAINT T_INFORMATION_TEACHERSEX_CK CHECK
(
TEACHERSEX = '1' OR TEACHERSEX = '2'
)
)
创建之后查看如图:
(2) 目前要统计全市中学的男女老师数量,写出完整语句。
SELECT
SUM(CASE WHEN TEACHERSEX='1' THEN 1 ELSE 0 END) AS 全市的男老师数量,
SUM(CASE WHEN TEACHERSEX='2' THEN 1 ELSE 0 END) AS 全市的女老师数量
FROM TEACHER_INFORMATION
(3) 目前要统计“树德中学”的职称为“高级教师”的老师数量,写出完整语句。
SELECT COUNT(*)
FROM SCHOOL_INFORMATION a,TEACHER_LEVEL b,TEACHER_INFORMATION c
WHERE a.SCHOOLID=c.SCHOOLID AND b.TLEVELID=c.TLEVELID
AND a.SCHOOLNAME='树德中学'
AND b.TLEVELNAME='高级教师'
(4) 目前要查询“石室中学”的职称为“中级教师”职称的男老师姓名,写出完整语句。(假设职称顺序为 实习教师、初级教师、中级教师、高级教师)
SELECT c.TEACHERNAME
FROM SCHOOL_INFORMATION a,TEACHER_LEVEL b,TEACHER_INFORMATION c
WHERE a.SCHOOLID=c.SCHOOLID AND b.TLEVELID=c.TLEVELID
AND a.SCHOOLNAME='石室中学'
AND b.TLEVELNAME='中级教师' AND c.TEACHERSEX='1'
(5) 目前要查询本市青年老师(年龄为20-30)岁的月平均收入,写出完整语句。
参考代码如下:
SELECT (SUM(a.TLEVALSAL)+SUM(a.TLEVALCOMM))/COUNT(*) AS 青年老师月平均收入
FROM TEACHER_LEVEL a,TEACHER_INFORMATION b
WHERE a.TLEVELID=b.TLEVELID AND
TRUNC((to_char(sysdate, 'yyyyMMdd') - to_char(b.TEACHERBIRTH, 'yyyyMMdd'))/10000)
BETWEEN 20 AND 30
首先解决从身份证得知现在的年龄的SQL参考代码。
先创建一个测试用例(因为实验的数据来自数据库课程的实验二数据,所以直接拿来用来测试)
-- ----------------------------
-- Table structure for "BONUS"
-- ----------------------------
CREATE TABLE "BONUS" (
"ENAME" VARCHAR2(10 BYTE) NULL ,
"JOB" VARCHAR2(9 BYTE) NULL ,
"SAL" NUMBER NULL ,
"COMM" NUMBER NULL
)
LOGGING
NOCOMPRESS
NOCACHE
;
-- ----------------------------
-- Table structure for "DEPT"
-- ----------------------------
CREATE TABLE "DEPT" (
"DEPTNO" NUMBER(2) NOT NULL ,
"DNAME" VARCHAR2(14 BYTE) NULL ,
"LOC" VARCHAR2(13 BYTE) NULL
)
LOGGING
NOCOMPRESS
NOCACHE
;
-- ----------------------------
-- Records of DEPT
-- ----------------------------
INSERT INTO "DEPT" VALUES ('10', 'ACCOUNTING', 'NEW YORK');
INSERT INTO "DEPT" VALUES ('20', 'RESEARCH', 'DALLAS');
INSERT INTO "DEPT" VALUES ('30', 'SALES', 'CHICAGO');
INSERT INTO "DEPT" VALUES ('40', 'OPERATIONS', 'BOSTON');
-- ----------------------------
-- Table structure for "EMP"
-- ----------------------------
CREATE TABLE "EMP" (
"EMPNO" NUMBER(4) NOT NULL ,
"ENAME" VARCHAR2(10 BYTE) NULL ,
"JOB" VARCHAR2(9 BYTE) NULL ,
"MGR" NUMBER(4) NULL ,
"HIREDATE" DATE NULL ,
"SAL" NUMBER(7,2) NULL ,
"COMM" NUMBER(7,2) NULL ,
"DEPTNO" NUMBER(2) NULL
)
LOGGING
NOCOMPRESS
NOCACHE
;
-- ----------------------------
-- Records of EMP
-- ----------------------------
INSERT INTO "EMP" VALUES ('7369', 'SMITH', 'CLERK', '7902', TO_DATE('1980-12-
17 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '800', null, '20');
INSERT INTO "EMP" VALUES ('7499', 'ALLEN', 'SALESMAN', '7698', TO_DATE('1981-
02-20 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '1600', '300', '30');
INSERT INTO "EMP" VALUES ('7521', 'WARD', 'SALESMAN', '7698', TO_DATE('1981-
02-22 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '1250', '500', '30');
INSERT INTO "EMP" VALUES ('7566', 'JONES', 'MANAGER', '7839', TO_DATE('1981-
04-02 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '2975', null, '20');
INSERT INTO "EMP" VALUES ('7654', 'MARTIN', 'SALESMAN', '7698', TO_DATE('1981-
09-28 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '1250', '1400', '30');
INSERT INTO "EMP" VALUES ('7698', 'BLAKE', 'MANAGER', '7839', TO_DATE('1981-
05-01 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '2850', null, '30');
INSERT INTO "EMP" VALUES ('7782', 'CLARK', 'MANAGER', '7839', TO_DATE('1981-
06-09 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '2450', null, '10');
INSERT INTO "EMP" VALUES ('7788', 'SCOTT', 'ANALYST', '7566', TO_DATE('1987-
04-19 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '3000', null, '20');
INSERT INTO "EMP" VALUES ('7839', 'KING', 'PRESIDENT', null, TO_DATE('1981-
11-17 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '5000', null, '10');
INSERT INTO "EMP" VALUES ('7844', 'TURNER', 'SALESMAN', '7698', TO_DATE('1981-
09-08 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '1500', '0', '30');
INSERT INTO "EMP" VALUES ('7876', 'ADAMS', 'CLERK', '7788', TO_DATE('1987-05-
23 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '1100', null, '20');
INSERT INTO "EMP" VALUES ('7900', 'JAMES', 'CLERK', '7698', TO_DATE('1981-12-
03 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '950', null, '30');
INSERT INTO "EMP" VALUES ('7902', 'FORD', 'ANALYST', '7566', TO_DATE('1981-
12-03 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '3000', null, '20');
INSERT INTO "EMP" VALUES ('7934', 'MILLER', 'CLERK', '7782', TO_DATE('1982-
01-23 00:00:00', 'yyyy-MM-dd HH24:mi:ss'), '1300', null, '10');
-- ----------------------------
-- Table structure for "SALGRADE"
-- ----------------------------
CREATE TABLE "SALGRADE" (
"GRADE" NUMBER NULL ,
"LOSAL" NUMBER NULL ,
"HISAL" NUMBER NULL
)
LOGGING
NOCOMPRESS
NOCACHE
;
-- ----------------------------
-- Records of SALGRADE
-- ----------------------------
INSERT INTO "SALGRADE" VALUES ('1', '700', '1200');
INSERT INTO "SALGRADE" VALUES ('2', '1201', '1400');
INSERT INTO "SALGRADE" VALUES ('3', '1401', '2000');
INSERT INTO "SALGRADE" VALUES ('4', '2001', '3000');
INSERT INTO "SALGRADE" VALUES ('5', '3001', '9999');
-- ----------------------------
-- Primary Key structure for table "DEPT"
-- ----------------------------
ALTER TABLE "DEPT" ADD CONSTRAINT PK_DEPT PRIMARY KEY ("DEPTNO");
-- ----------------------------
-- Primary Key structure for table "EMP"
-- ----------------------------
ALTER TABLE "EMP" ADD CONSTRAINT PK_EMP PRIMARY KEY ("EMPNO");
-- ----------------------------
-- Foreign Key structure for table "EMP"
-- ----------------------------
ALTER TABLE "EMP" ADD CONSTRAINT FK_DEPTINO FOREIGN KEY ("DEPTNO") REFERENCES
"DEPT" ("DEPTNO");
创建好后,就有三张表,如图:
DEPT表的“数据”内容
EMP表的“数据”内容
SALGRADE表的“数据”内容
在数据库中的表创建并输入数据后,我们先查看各个员工到现在是多少岁? 就是使用系统时间-他们身份证上面的【年月日】,得到结果。
/*查询各个员工的年龄代码*/
SELECT TRUNC((to_char(sysdate, 'yyyyMMdd') - to_char(HIREDATE, 'yyyyMMdd'))/10000) AS AGE
FROM EMP
如图所示,在实验二中测试代码可以查询各个员工的年龄
/*实验二当中求34-39年龄段的员工信息*/
SELECT *
FROM EMP
WHERE TRUNC((to_char(sysdate, 'yyyyMMdd') - to_char(HIREDATE, 'yyyyMMdd'))/10000)
BETWEEN 34 AND 39
如图所示,查找年龄段为34-39的所有员工信息
所以,第(5)题要查询本市青年老师(年龄为20-30)岁的信息
/*青年老师(年龄为20-30)岁的信息*/
SELECT *
FROM TEACHER_INFORMATION
WHERE TRUNC((to_char(sysdate, 'yyyyMMdd') - to_char(TEACHERBIRTH, 'yyyyMMdd'))/10000)
BETWEEN 20 AND 30
现在已经筛选出本市青年老师(年龄为20-30)岁,但是他们的月平均收入应该使用哪一个函数来进行计算呢?
- AVG(SAL+COMM)
- AVG(SAL)
- AVG(COMM)
- (AVG(SAL)+AVG(COMM))
- AVG(SAL+COMM)
- SUM(SAL+COMM)
- (SUM(SAL)+SUM(COMM))/COUNT(*)
我们计算一下他们的结果:
AVG(SAL+COMM)
-------------
1950
AVG(SAL)
----------
2077.08333
AVG(COMM)
----------
550
(AVG(SAL)+AVG(COMM))
--------------------
2627.08333
AVG(SAL+COMM)
-------------
1950
SUM(SAL+COMM)
-------------
7800
(SUM(SAL)+SUM(COMM))/COUNT(*)
-----------------------------
2260.41667
实验二中计算39-40的总收入,即每个人的工资+津贴,最终表达式应该为
(SUM(SAL)+SUM(COMM))/COUNT(*)
-----------------------------
2260.41667
AVG(COMM),(AVG(SAL)+AVG(COMM)),SUM(SAL+COMM)都只会把有COMM的计算进去,没有的就不算一个数据了,这个不好。AVG(SAL+COMM)不知道为什么不正确,但是最终,(SUM(SAL)+SUM(COMM))/COUNT(*)这个才是正确解法。
实验二中测试代码如下:这个是EMP表的数据,计算39-40的每个人 工资和津贴总和再除以39-40的人数才是正确的
查询工作为'SALESMAN',并且工龄为39-40之间的员工信息,成功执行。
查询本市青年老师(年龄为20-30)岁的月平均收入的一种正确代码应该如下:
SELECT (SUM(a.TLEVALSAL)+SUM(a.TLEVALCOMM))/COUNT(*) AS 青年老师月平均收入
FROM TEACHER_LEVEL a,TEACHER_INFORMATION b
WHERE a.TLEVELID=b.TLEVELID AND
TRUNC((to_char(sysdate, 'yyyyMMdd') - to_char(b.TEACHERBIRTH, 'yyyyMMdd'))/10000)
BETWEEN 20 AND 30
可以考虑使用mounth between函数计算sysdate