SQL查询某个年龄段的月平均收入的思考

以下算式,在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语句练习

(1)    定义各表,写出完整语句。

a.        SCHOOL_INFORMATION(学校基础信息表)

b.        TEACHER_LEVEL(教师职称、工资标准表)

c.        TEACHER_ INFORMATION(教师基本信息表)

(2)    目前要统计全市中学的男女老师数量,写出完整语句。 

(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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值