我正在尝试为我的oracle表单创建摘要。此摘要将存储每个部门的员工数量。记录不存储在一个表中,其中不同的列表示部门名称(例如小时,它......) 代码:
create table cleaners
(
ceno INTEGER,
cname VARCHAR(5)
);
create table drivers
(
eno INTEGER,
dname VARCHAR(5)
);
create table mechanics
(
eno INTEGER,
mname VARCHAR(5)
);
INSERT INTO cleaners VALUES ('1','3');
INSERT INTO cleaners VALUES ('2','3');
INSERT INTO cleaners VALUES ('3','3');
INSERT INTO cleaners VALUES ('4','2');
INSERT INTO cleaners VALUES ('5','2');
INSERT INTO drivers VALUES ('5','3');
INSERT INTO drivers VALUES ('4','3');
INSERT INTO drivers VALUES ('3','3');
INSERT INTO drivers VALUES ('2','2');
INSERT INTO drivers VALUES ('1','2');
INSERT INTO mechanics VALUES ('5','3');
INSERT INTO mechanics VALUES ('4','3');
INSERT INTO mechanics VALUES ('3','3');
INSERT INTO mechanics VALUES ('2','2');
INSERT INTO mechanics VALUES ('1','2');
create view summary as select
count(cleaners.eno) as numberofcleaners,
count(drivers.eno) as numberofdrivers,
count(mechanics.eno) as numberofmechanics,
from cleaners, drivers, mechanics;
所以我的目标是让每一个部门的所有数字都有一行。但是查询返回相乘的结果。应该怎么做?我使用的是Oracle6i,这是一个没有商业化的学校项目。
答案 0 :(得分:11)
由于这是一项家庭作业,我想就如何以适当的方式设计表格提供一些意见。只是我的两分钱。
我建议你改变表格设计。您的所有表基本上都包含相同的数据:
不应该有多个表,而应该沿着这一行设计一个只包含两个表的数据库。
Department
----------
dept_no INTEGER
dept_name VARCHAR(30)
Person
------
person_no INTEGER
person_name VARCHAR(30)
dept_no INTEGER
您应该设计具有适当约束的表。这里有几点需要注意。
正如名称所述,约束PRIMARY KEY
将在表上创建一个主键,以保持数据的唯一性,这样您就不会得到具有相同值的多个ID。
约束FOREIGN KEY
正在创建表Department和Person之间的关系。
对于此示例,这些键可能不是必需的,但在实际应用程序中,使用外键约束定义正确关系始终是最佳实践。您可以在网络上搜索关于PRIMARY KEY
和FOREIGN KEY
的许多其他内容。
您无法切换创建这些表的顺序。换句话说,您不能先创建Person表,然后再创建Department表。原因是Person表正在创建一个引用Department表的约束。如果先创建Person表,则会收到错误Failed: ORA-00942: table or view does not exist
。
您还可以将dept_no
和person_no
设置为自动递增的数字,这样您就不必手动插入这些数字。我使用SQL Server。所以,我不太熟悉Oracle语法,以使列成为自动递增的数字。搜索Oracle的序列号,您可能会发现一些内容。
脚本:
CREATE TABLE Department
(
dept_no INTEGER
, dept_name VARCHAR(30)
, CONSTRAINT pk_department PRIMARY KEY (dept_no)
);
CREATE TABLE Person
(
person_no INTEGER
, person_name VARCHAR(30)
, dept_no INTEGER
, CONSTRAINT pk_person PRIMARY KEY (person_no)
, CONSTRAINT fk_person_dept FOREIGN KEY (dept_no)
REFERENCES Department (dept_no)
);
下面给出的脚本首先填充Department表,然后填充Person表。
它实际上是在同一时间向表中插入多个值,而不是为每一行调用INSERT INTO。
dual 是Oracle中具有单行的虚拟表。 Read here in this SO answer about dual.
脚本:
INSERT ALL
INTO Department (dept_no, dept_name) VALUES (1, 'Cleaner')
INTO Department (dept_no, dept_name) VALUES (2, 'Driver')
INTO Department (dept_no, dept_name) VALUES (3, 'Mechanic')
SELECT * FROM dual;
INSERT ALL
INTO Person (person_no, person_name, dept_no) VALUES (1, 'Cleaner 1', 1)
INTO Person (person_no, person_name, dept_no) VALUES (2, 'Cleaner 2', 1)
INTO Person (person_no, person_name, dept_no) VALUES (3, 'Cleaner 3', 1)
INTO Person (person_no, person_name, dept_no) VALUES (4, 'Cleaner 4', 1)
INTO Person (person_no, person_name, dept_no) VALUES (5, 'Driver 1', 2)
INTO Person (person_no, person_name, dept_no) VALUES (6, 'Driver 2', 2)
INTO Person (person_no, person_name, dept_no) VALUES (7, 'Driver 3', 2)
INTO Person (person_no, person_name, dept_no) VALUES (8, 'Mechanic 1', 3)
INTO Person (person_no, person_name, dept_no) VALUES (9, 'Mechanic 2', 3)
INTO Person (person_no, person_name, dept_no) VALUES (10, 'Mechanic 3', 3)
INTO Person (person_no, person_name, dept_no) VALUES (11, 'Mechanic 4', 3)
INTO Person (person_no, person_name, dept_no) VALUES (12, 'Mechanic 5', 3)
INTO Person (person_no, person_name, dept_no) VALUES (13, 'Mechanic 6', 3)
SELECT * FROM dual;
现在您已拥有表格和数据,现在可以查询信息了。
您的要求是获取所有部门的列表以及每个部门的人数。
如果您运行以下查询,您只需获取部门列表,但这不是您所需要的。
简单选择:
SELECT dept_no
, dept_name
FROM Department;
输出:
DEPT_NO DEPT_NAME
------- ---------
1 Cleaner
2 Driver
3 Mechanic
INNER JOIN
加入公共字段上的两个表。在这种情况下,两个表中的公共字段是 dept_no 。 脚本:
SELECT d.dept_no
, d.dept_name
, COUNT(p.person_no) AS No_of_employees
FROM Department d
INNER JOIN Person p
ON p.dept_no = d.dept_no
GROUP BY d.dept_no
, d.dept_name
ORDER BY d.dept_no;
输出:
DEPT_NO DEPT_NAME NO_OF_EMPLOYEES
------- --------- ---------------
1 Cleaner 4
2 Driver 3
3 Mechanic 6
查询使用了很多东西,比如INNER JOIN,GROUP BY,COUNT和ORDER BY。让我们看看其中的每一个。
INNER JOIN 根据公共字段加入表格,在本例中为dept_no。
COUNT 功能将允许查询组按部门编号和部门名称计算所有员工数。
COUNT
是一个聚合函数。将聚合函数与非聚合列一起使用时,需要使用GROUP BY子句。这里dept_no和dept_name是非聚合列。 SUM
,MAX
。 MIN
是一些集合函数。
最后,我们应用 ORDER BY 子句按 dept_no 列对输出进行排序。
答案 1 :(得分:1)
您正在查询中进行交叉加入。试试这个:
create view summary
as
select
(select count(cleaners.eno) from cleaners) as numberofcleaners,
(select count(drivers.eno) from drivers ) as numberofdrivers,
(select count(mechanics.eno) from mechanics) as numberofmechanics
from dual;