Coding a SUM in a View in Oracle - oracle

I am stuck in a progaramming problem in Oracle, that I am trying to solve.
I am suppose to create a View that will give me the total hours flown EVER, for crew of the FBN001 on the 27th october 2016
This is the Flight Table:
CREATE TABLE Flight(
Flight_ID VARCHAR(25),
Route_ID VARCHAR(25),
Airplane_ID VARCHAR(10),
Departure_Time DATE,
Arrival_Time DATE,
CONSTRAINT FlightIDPK PRIMARY KEY(Flight_ID),
CONSTRAINT RouteIDFK FOREIGN KEY(Route_ID) REFERENCES Route(Route_ID),
CONSTRAINT AirplaneIDFK FOREIGN KEY(Airplane_ID) REFERENCES Airplane(Airplane_ID));
And this is the Crew Table:
CREATE TABLE Crew(
Crew_ID NUMBER(10),
Flight_ID VARCHAR(25),
Role VARCHAR(25) NOT NULL,
Employee_ID NUMBER(10),
Hours NUMBER(10),
CONSTRAINT CrewIDPK PRIMARY KEY(Crew_ID),
CONSTRAINT EmployeeIDFK FOREIGN KEY(Employee_ID) REFERENCES Employee(Employee_ID));
I thought i would use the SUM Function:
CREATE VIEW ViewC AS(
SELECT Flight.Route_ID, Crew.Employee_ID, SUM(Hours)AS TotalHoursFlew
FROM Crew, Flight
WHERE Crew.Flight_ID = Flight.Flight_ID
AND Route_ID = 'FBN001');
but that isnt working?
what could be the solution?
Thank you

You need a GROUP BY:
CREATE VIEW ViewC AS(
SELECT Flight.Route_ID, Crew.Employee_ID, SUM(Hours)AS TotalHoursFlew
FROM Crew, Flight
WHERE Crew.Flight_ID = Flight.Flight_ID
AND Route_ID = 'FBN001'
GROUP BY Flight.Route_ID, Crew.Employee_ID);

Related

ORA-02267: incompatible with the data type or collation of the referenced column

create table doctor
(
name varchar2(20)
, d_id varchar2(20)
, address varchar2(50)
, phone_number number(10)
, qualification varchar2(20)
, gender varchar2(20)
, constraint pk_doctor primary key(d_id)
)
;
create table room
(
room_id varchar2(5)
, room_type varchar2(20)
, constraint pk_room primary key(room_id)
)
;
create table patient
(
p_id varchar2(10)
, p_name varchar2(20)
, p_age number(3)
, p_gender varchar2(10)
, address varchar2(50)
, date_admission date
, phone_number number(10)
, room_id varchar2(5)
, constraint pk_patient primary key(p_id)
, constraint fk_p1 foreign key(room_id) references room
)
;
create table bill
(
bill_no varchar2(10)
, bill_date date
, p_id varchar2(10)
, p_name varchar2(20)
, p_age number(3)
, p_gender varchar2(10)
, date_admission date
, date_discharge date
, room_charges number(10)
, pathology_fees number(10)
, d_fees number(10)
, miscellaneous number(10)
, total_amount number(10)
, constraint pk_bill primary key(bill_no)
, constraint fk_b1 foreign key(p_id) references patient
, constraint fk_b2 foreign key(p_name) references patient
, constraint fk_b3 foreign key(p_age) references patient
, constraint fk_b4 foreign key(p_gender) references patient
, constraint fk_b5 foreign key(date_admission) references patient
)
;
Error starting at line : 15 in command -
create table bill
(
bill_no varchar2(10)
, bill_date date
, p_id varchar2(10)
, p_name varchar2(20)
, p_age number(3)
, p_gender varchar2(10)
, date_admission date
, date_discharge date
, room_charges number(10)
, pathology_fees number(10)
, d_fees number(10)
, miscellaneous number(10)
, total_amount number(10)
, constraint pk_bill primary key(bill_no)
, constraint fk_b1 foreign key(p_id) references patient
, constraint fk_b2 foreign key(p_name) references patient
, constraint fk_b3 foreign key(p_age) references patient
, constraint fk_b4 foreign key(p_gender) references patient
, constraint fk_b5 foreign key(date_admission) references patient
)
Error report -
ORA-02267: column type incompatible with referenced column type
02267. 00000 - "column type incompatible with referenced column type"
*Cause: The data type or collation of the referencing column was
incompatible with the data type or collation of the referenced
column.
*Action: Select a compatible data type for the referencing column.
Also, the collation of a character column in a foreign key must
match the collation of the corresponding column in the primary
key.
I understand what the error is trying to tell but my datatypes are same in both tables but still, it is showing the error??
Please tell me where I made a mistake. I would be very grateful.
From the documentation:
If you identify only the parent table or view and omit the column name, then the foreign key automatically references the primary key of the parent table or view.
So you're effectively actually doing:
, constraint fk_b1 foreign key(p_id) references patient
, constraint fk_b2 foreign key(p_name) references patient(p_id)
, constraint fk_b3 foreign key(p_age) references patient(p_id)
, constraint fk_b4 foreign key(p_gender) references patient(p_id)
, constraint fk_b5 foreign key(date_admission) references patient(p_id)
which obviously isn't what you want, and explains the error you get.
You need to specify the matching non-PK columns:
, constraint fk_b1 foreign key(p_id) references patient
, constraint fk_b2 foreign key(p_name) references patient(p_name)
, constraint fk_b3 foreign key(p_age) references patient(p_age)
, constraint fk_b4 foreign key(p_gender) references patient(p_gender)
, constraint fk_b5 foreign key(date_admission) references patient(date_admission)
However, this will not get
ORA-02270: no matching unique or primary key for this column-list
because those four columns aren't suitable targets; none can really be unique, at least safely. And it wouldn't allow data to change - name and gender could, but age will, for example. These may be recording the patient's status on admission though, so then those wouldn't change, other than to correct mistakes.
It doesn't really make sense to duplicate/denormalise the data. You can just have the PK reference and join to the main table as needed to get the other information.
db<>fiddle
Splitting patient into a table to identify an individual (with date of birth rather than age) and a separate table that records each stay for that patient - with room and admission/discharge dates, for example - might make more sense. Only recording the discharge date on the bill seems odd.
The problem you're facing comes from bad data model which is needed for some rework.
The "bill" table contains p_name, p_age, p_gender, and date_admission columns. Same columns exist in the "patient" table, so you don't need them in the "bill". Just remove the columns from the "bill" definition and it'll be fine.
Whenever you need to get patient's name for the bill, you can always get it using p_id:
select p.p_name, p.p_age
from patient p
join bill b
on b.p_id, p.p_id
where b.bill_no = 'some_bill_no'
And keeping patient's age will lead to an engineering overhead because you'll have to update this field constantly once per year. I'd suggest you to store patient's birth_date and calculate his/her age when needed.
Of course when it is not a homework with gives table structure

how to create a foreign key in Oracle

How to link the MgrId in ManagerProject to EmpId in the Employee table ?
This is wat I tried :
CREATE TABLE Employee(EmpId varchar2(5),
EmpName varchar2(25),
DeptId varchar2(3),
Salary Number(8),
Constraint PK_addn primary key (EmpId, DeptId),
Constraint fk_Department foreign key (DeptId) references Department (DeptId));
But the second table failed to be created :
CREATE TABLE ManagerProject(ProjId varchar2(4),
MgrId varchar2(5),
StartDate Date,
EndDate Date,
Constraint fk_managerproject foreign key (MgrId) references Employee (EmpId),
Constraint PK_Managerproject Primary key(ProjId, MgrId, StartDate));
It displays
ORA-02270: no matching unique or primary key for this column-list
The error message says that you are trying to create a FK referencing a column on which there is no Unique or Primary Key constraint.
Assuming that you don't want to add the column DeptId to ManagerProject, you need to add a unique key on employee:
alter table Employee add constraint empId_UK unique ( empId)
But this strongly depends on what your schema should be.
If you want to add the column DeptId to ManagerProject, you will need to edit your FK to both use EmpId and DeptId in referencing employee.

Coding a COUNT in a VIEW in Oracle

I am stuck in a programming problem in Oracle, that I am trying to solve. I am suppose to create a View that will give me the Number of unreserved/Available seats on FBN001 ON 27TH October 2016
This is the Flight Table:
CREATE TABLE Flight(
Flight_ID VARCHAR(25),
Route_ID VARCHAR(25),
Airplane_ID VARCHAR(10),
Departure_Time DATE,
Arrival_Time DATE,
CONSTRAINT FlightIDPK PRIMARY KEY(Flight_ID),
CONSTRAINT RouteIDFK FOREIGN KEY(Route_ID) REFERENCES Route(Route_ID),
CONSTRAINT AirplaneIDFK FOREIGN KEY(Airplane_ID) REFERENCES Airplane(Airplane_ID));
This is the Airplane Table:
CREATE TABLE Airplane(
Airplane_ID VARCHAR(10),
Capacity NUMBER(5) NOT NULL,
Model VARCHAR(15) NOT NULL,
CONSTRAINT AirplaneIDPK PRIMARY KEY(Airplane_ID));
This is the Booking Table:
CREATE TABLE Booking(
Booking_ID NUMBER(10),
Flight_ID VARCHAR(25),
Customer_ID NUMBER(10),
Payment_Method VARCHAR(10) NOT NULL,
CreditCard_Details NUMBER(18),
CONSTRAINT BookingIDPK PRIMARY KEY(Booking_ID),
CONSTRAINT FlightIDFK FOREIGN KEY(Flight_ID) REFERENCES Flight(Flight_ID),
CONSTRAINT CustomerIDFK FOREIGN KEY(Customer_ID) REFERENCES Customer(Customer_ID));
I thought i would use the COUNT function to count the Bookings
CREATE VIEW ViewB AS(
SELECT Flight.Route_ID, Flight.Departure_Time, Airplane.Capacity, COUNT(Flight_ID) AS NumberOfBooking
FROM Flight, Airplane, Booking
WHERE Flight.Airplane_ID = Airplane.Airplane_ID
AND Flight.Route_ID = 'FBN001'
GROUP BY Flight.Route_ID, Airplane.Capacity);
But that did not work,
It is giving me the Error
Error report -
SQL Error: ORA-00918: column ambiguously defined
00000 - "column ambiguously defined"
*Cause:
*Action:
What could be the solution?
Thank you
You didn't add a statement to properly join the booking table:
CREATE VIEW ViewB AS(
SELECT Flight.Route_ID, Flight.Departure_Time, Airplane.Capacity, COUNT(Flight_ID) AS NumberOfBooking
FROM Flight, Airplane, Booking
WHERE Flight.Airplane_ID = Airplane.Airplane_ID
AND Flight.Flight_ID=Booking.Flight_ID
AND Flight.Route_ID = 'FBN001'
GROUP BY Flight.Route_ID, Airplane.Capacity);

Triggers in oracle PL/SQL

I am trying to do a trigger that updates a sum of all credits on update of the grade or a insert of a new one. That's my tables
create table Department (
Department_ID varchar(4) not null,
Name varchar(25) unique,
Department_Head_ID varchar(9),
College_ID varchar(4),
Credits_To_Degree NUMBER(3),
constraint pkDepartment primary key (Department_ID));
create table Enrollment (
Student_ID varchar(9) not null,
Course_ID varchar(5) not null,
Registered_Date date,Grade NUMBER,
Status varchar(4),constraint pkEnrollment primary key
(Student_ID, Course_ID));
create table Student (
Student_ID varchar(9) not null,
First_Name varchar(25),
Last_Name varchar(25),
Phone char(11),
Birth_Date date,
Street varchar(100),
Zip_Code char(5),
Department varchar(4),
Credits integer,
Eligible char(4), constraint pkStudent primary key
(Student_ID),constraint fkDeptId foreign key (Department)
references Department(Department_ID));
ALTER TABLE Department ADD FOREIGN KEY (Department_Head_ID)
REFERENCES Faculty(Faculty_Id) INITIALLY DEFERRED;
ALTER TABLE Department ADD FOREIGN KEY(College_ID) REFERENCES
College(College_ID) INITIALLY DEFERRED;
the trigger:
create or replace TRIGGER Credits
after INSERT OR UPDATE
ON enrollment
REFERENCING NEW AS New OLD AS Old
FOR EACH ROW
BEGIN
UPDATE STUDENT
SET CREDITS=(SELECT SUM(c.CREDITS) FROM COURSE c,ENROLLMENT e
WHERE c.COURSE_ID = e.COURSE_ID
and e.STUDENT_ID = :new.student_id
and e.GRADE>= 60 )
WHERE STUDENT.STUDENT_ID=:new.student_id;
END;
The trigger compiles but when i change value of the grade a get this error
UPDATE "FELIX"."ENROLLMENT" SET GRADE = '60' WHERE ROWID = 'AAAGUSAABAAALKJAAF' AND ORA_ROWSCN = '3540016'
ORA-20003: An error has occurred while performing credits trigger
ORA-06512: at "FELIX.CREDITS", line 5
ORA-04088: error during execution of trigger 'FELIX.CREDITS'
One error saving changes to table "FELIX"."ENROLLMENT":
Row 6: ORA-20003: An error has occurred while performing credits trigger
ORA-06512: at "FELIX.CREDITS", line 5
ORA-04088: error during execution of trigger 'FELIX.CREDITS'
line 5 is a FOR EACH ROW command
I figure out that the problem is in the :new.student_id. But how could i get the id of the row that the triggers fires upon.
Thanks in advance for the help.

Employee/History - Part of composite key as foreign key

I've got 2 entities:
1) EMPLOYEES (Parent)
CREATE TABLE EMPLOYEES (
employee_id NUMBER (3) NOT NULL,
first_name VARCHAR (20) NOT NULL,
last_name VARCHAR (20) NOT NULL,
job_title VARCHAR (20) NOT NULL,
employee_type VARCHAR (1) NOT NULL,
salary NUMBER (5),
hourly_pay NUMBER (5,2),
bonus_pay NUMBER (5,2),
CONSTRAINT employee_pk PRIMARY KEY(employee_id));
2) EMPLOYEE_HISTORY (Child)
CREATE TABLE EMPLOYEE_HISTORY (
start_date DATE NOT NULL,
employee_id NUMBER (3) NOT NULL,
end_date DATE,
job_title VARCHAR (10) NOT NULL,
hourly_rate NUMBER (5,2) NOT NULL,
CONSTRAINT employee_history_pk PRIMARY KEY(start_date, employee_id));
I'm trying to create:
ALTER TABLE employee_history
ADD CONSTRAINT employee_history_fk
FOREIGN KEY (employee_id)
REFERENCES employee_history(employee_id);
When I do this, I get an error
ORA-02270: no matching unique or primary key for this column-list
My guess is that I cannot create the constraint on just employee_id because I have a composite key in my child table. I understand when an employee gets put into the database, the parent table is filled out and the "start date" should be filled out along with everything else. However, I do not understand how this would work if I had start_date in my parent table as well. I would be able to create my constraint, yes, but how will I be able to keep a record of changes in start_date if my start_date was inputted at the time of when the employee was entered into the database.I thought about using job_title as a primary key instead of start_date because it's present in both tables, but what happens when an employee gets promoted and demoted again? Won't a duplicate value constraint come up when the same employee_id and job_title is getting inserted?
Your references clause needs to reference the parent table. Not the child table
ALTER TABLE employee_history
ADD CONSTRAINT employee_history_fk
FOREIGN KEY (employee_id)
REFERENCES employee(employee_id); -- employee not employee_history
The SQL you posted is trying to create a self-referential foreign key where employee_history is both the parent and the child. That doesn't make sense in this case.

Resources