I am trying to create summary for my oracle form. This summary would store number of employees for each department. Records are not stored in one table where would be different column indicating name of department(ex. hr, it …)
code:
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;
So my aim is to have one row with all numbers of each department. However the query is returning multiplied result. How should it be done? I am using Oracle6i, this is a school project nothing commercial.
Since this is a homework assignment, I would like to provide some input on how to design the tables in a proper manner. Just my two cents.
Design suggestion
I would suggest that you alter the table design. All your tables essentially contain the same data:
Instead of having multiple tables, you should design your database something along this line that would include only two tables.
Create tables with constraints
You should design tables with appropriate constraints. Here are few things to note.
The constraint
PRIMARY KEY, as the name states, would create a primary key on the table to keep the data unique so that you don’t end up with multiple ids with the same value.The constraint
FOREIGN KEYis creating a relation between the tables Department and Person.For this example, these keys may not be necessary but in real world applications it is always a best practice to define proper relations using the foreign key constraints. There are lots of other things you can search about
PRIMARY KEYandFOREIGN KEYon the web.You cannot switch the order in which these tables are created. In other words, you cannot create Person table first and then the Department table. The reason is that Person table is creating a constraint that references the Department table. If you create the Person table first, you will get the error
Failed: ORA-00942: table or view does not exist.You can also make the
dept_noandperson_noto be auto incremented numbers so that you don’t have to manually insert those numbers. I use SQL Server. So, I am not much familiar with Oracle syntax to make a column to auto incremented number. Search for sequence number for Oracle, you might find something.Script:
Populate the table
Below given script first populates the Department table and then populates the Person table.
It is actually inserting multiple values into the table at the same time instead of calling INSERT INTO for every single row.
dual is a dummy table in Oracle with single row. Read here in this SO answer about dual.
Script:
How to get my data grouped by department?
Now that you have the table and data, it is time to query the information.
Your requirement is to get the list of all the departments and the number of people in each department.
If you run the following query, you will simply get the list of departments but that is not what you need.
Simple Select:
Output:
INNER JOINto join both the tables on a common field. In this case, the common field in both the tables is dept_no.Query that will give you the desired output
Script:
Output:
Explanation
The query uses quite a few things like INNER JOIN, GROUP BY, COUNT and ORDER BY. Let’s look each one of these.
INNER JOIN joins the tables based on the common field, in this case dept_no.
COUNT function would allow the query group all the count of employees by their department number and department name.
COUNTis an aggregate function. When you use an aggregate function with non-aggregate columns, then you need to use GROUP BY clause. Here the dept_no and dept_name are non-aggregate columns.SUM,MAX.MINare some of the aggregate functions.Finally, we apply the ORDER BY clause to sort the output by dept_no column.
Demo
Click here to view the demo in SQL Fiddle.