Missing right parenthesis- ORA-00907 - oracle

select distinct student.ID
from (student join takes using(ID))
join (instructor join teaches using(ID))
using(course_id, sec_id, semester, year)
where instructor.name = 'Einstein'
As rightly pointed out Bob, there was a '_' in that. But now it says USING cannot have qualifier.
Student :
create table student
(ID varchar(5),
name varchar(20) not null,
dept_name varchar(20),
tot_cred numeric(3,0) check (tot_cred >= 0),
primary key (ID),
foreign key (dept_name) references department
on delete set null
)
Takes:
create table takes
(ID varchar(5),
course_id varchar(8),
sec_id varchar(8),
semester varchar(6),
year numeric(4,0),
grade varchar(2),
primary key (ID, course_id, sec_id, semester, year),
foreign key (course_id,sec_id, semester, year) references section
on delete cascade,
foreign key (ID) references student
on delete cascade
)
Instructor:
create table instructor
(ID varchar(5),
name varchar(20) not null,
dept_name varchar(20),
salary numeric(8,2) check (salary > 29000),
primary key (ID),
foreign key (dept_name) references department
on delete set null
)
Teaches :
create table teaches
(ID varchar(5),
course_id varchar(8),
sec_id varchar(8),
semester varchar(6),
year numeric(4,0),
primary key (ID, course_id, sec_id, semester, year),
foreign key (course_id,sec_id, semester, year) references section
on delete cascade,
foreign key (ID) references instructor
on delete cascade
);
I have pasted the structure as requested. I hope that helps!
I have also tried editing the quotes but still no use.

The problem is not that there are too few parentheses but that there are too many.
I'm guessing a bit here because I don't know exactly what your tables look like, but it appears that your SELECT statement should be:
select distinct student.ID
from student
join takes
using(ID)
join instructor
using(ID)
join teaches
using(course id, sec id, semester, year)
where instructor.name = 'Einstein'
In addition, you need to be careful about the editor you're using. In your question the single quotes surrounding 'Einstein' are not real single quotes - they appear to be Unicode apostrophes as would be added by a word processor such as Microsoft Word. String constants need to be surrounded by single quote characters (') - using anything else will cause errors.
Best of luck.

As Bob Jarvis pointed out, the third using clause has spaces where there should be underscores; changing those then gets (as you edited the question to say):
ORA-25154: column part of USING clause cannot have qualifier
because the select list has student.ID. When you use the using clause the column(s) in that can't be referenced directly in the joined tables, so you need to do:
select distinct ID
from (student join takes using(ID))
join (instructor join teaches using(ID))
using(course_id, sec_id, semester, year)
where instructor.name = 'Einstein';
... but that will now get
ORA-00918: column ambiguously defined
... because both student and instructor have ID columns, which is presumably why the select list was prefixed in the first place. You could use an inline view to lose the instructor ID from the select list scope:
select distinct ID
from (student join takes using(ID))
join (select course_id, sec_id, semester, year, name
from instructor join teaches using(ID)) instructor
using(course_id, sec_id, semester, year)
where instructor.name = 'Einstein';
But really you'd be better off avoiding using here and instead use the on syntax and simplified joins, e.g.:
select distinct stu.id
from instructor ins
join teaches tea on tea.id = ins.id
join takes tak on tak.course_id = tea.course_id
and tak.sec_id = tea.sec_id
and tak.semester = tea.semester
and tak.year = tea.year
join student stu on stu.id = tak.id
where ins.name = 'Einstein';
Also see an earlier related answer for more.

Related

one attribute referencing, attributes in two different tables

I have 4 tables
customer: CustomerID - primary key, name
Magazine: name - primary key, cost, noofissues
Newspaper: name - primary key, cost, noofissues
subscription: custID - references CustomerID of Customer, name, startdate, enddate
In the above, can I reference the name from subscription table to reference name from Magazine and name from Newspaper?
I have created the tables Customer, Newspaper and Magazine. I only need to create Subscription.
Can you do something like this?
CREATE TABLE subscription (
custID INT
CONSTRAINT subscription__custid__fk REFERENCES Customer( CustomerId ),
name VARCHAR2(50)
CONSTRAINT subscription__mag_name__fk REFERENCES Magazine( Name )
CONSTRAINT subscription__news_name__fk REFERENCES Newspaper( Name ),
startdate DATE
CONSTRAINT subscription__startdate__nn NOT NULL,
enddate DATE
);
Yes, you can and you will have two foreign keys on the same column pointing to different tables but if the value in the column is non-null then it will expect there to be a matching name in both the magazines table and the newspapers table - which is probably not what you are after.
Can you have a foreign key that asks can the value be in either exclusively in this table or that table (but not in both)? No.
But you can re-factor your database so you merge the newspapers and magazines tables into a single table (which you can then easily reference); like this:
CREATE TABLE customer (
CustomerID INT
CONSTRAINT customer__CustomerId__pk PRIMARY KEY,
name VARCHAR2(50)
CONSTRAINT customer__name__nn NOT NULL
);
CREATE TABLE Publications (
id INT
CONSTRAINT publications__id__pk PRIMARY KEY,
name VARCHAR2(50)
CONSTRAINT publications__name__nn NOT NULL,
cost NUMBER(6,2)
CONSTRAINT publications__cost__chk CHECK ( cost >= 0 ),
noofissues INT,
type CHAR(1),
CONSTRAINT publications__type__chk CHECK ( type IN ( 'M', 'N' ) )
);
CREATE TABLE subscription (
custID INT
CONSTRAINT subscription__custid__fk REFERENCES Customer( CustomerId ),
pubID INT
CONSTRAINT subscription__pubid__fk REFERENCES Publications( Id ),
startdate DATE
CONSTRAINT subscription__startdate__nn NOT NULL,
enddate DATE
);
If you are asking whether you can create a foreign key constraint on subscription that references either the newspaper table or the magazine table, the answer is no, you cannot. A foreign key must reference exactly one primary key.
Since magazine and newspaper have the same set of attributes, the simple option is to combine them into a single periodical table with an additional periodical_type column to indicate whether it is a magazine or a newspaper. You could then create your foreign key to the periodical table.
Although it probably won't make sense in this particular example, you could also have separate columns in subscription for magazine_name and newspaper_name and create separate foreign key constraints on those columns along with a check constraint that ensured that exactly one of the values was non-NULL. That might make sense if the two different parent tables had radically different attributes.
Not related to your question but as a general bit of advice, I wouldn't use the name as the primary key. In addition to being rather long, names tend to change over time and names aren't necessarily unique. I would use a different attribute for the key, potentially a synthetic primary key generated from a sequence.

Trigger Before Insert on multiple tables

I am fairly new to triggers and PL/SQL, so my question is mainly one of design.
I am creating a set of tables to represent ticket purchases. There are three types of tickets:
Ticket #1: Price, Quantity, Time
Ticket #2: Price, Quantity, Time, Seating, Refundable
Ticket #3: Price, Quantity, Time, Food , Drink
So I have created three tables: (I believe this is called, normalizing):
Table1 has columns Price, Quantity and Time
Table2 has Seating and Refundable
Table3 has Food and Drink
I have inserted a primary key column into Table1 and am using foreign keys in Table2 and Table3 which point to Table1's PK.
The Plan: When a user purchases a ticket, I insert a record into the appropriate table(s). For instance, if the user purchases:
Ticket #1, I insert a record into Table1
Ticket #2, I insert a record into Table1 and Table2
Ticket #3, I insert a record into Table1 and Table3
The Problem: How can I receive all the data for a ticket not of type 1, and then split the parameters to insert into the separate tables. For instance, when I try to create a trigger for Table2, that trigger can only receive the parameters that match what Table2 columns has. How can I receive the data for Table1?
An example of a complete purchase of ticket type 2.
User purchases ticket online -> web form stuff happends... -> dao sends ONE insert command to the database -> trigger for Table2 kicks off and validates info for Table1 and Table2.
Thanks!
You can design this in any way you want, but given that there's not much difference between the ticket types I'd have a single table:
CREATE TABLE TICKET
(ID_TICKET NUMBER
CONSTRAINT PK_TICKET
PRIMARY KEY
USING INDEX,
TICKET_TYPE NUMBER
NOT NULL
CONSTRAINT TICKET_CK1
CHECK(TICKET_TYPE IN (1, 2, 3)),
PRICE NUMBER
NOT NULL,
QUANTITY NUMBER
NOT NULL,
DEPARTURE_TIME DATE
NOT NULL,
SEATING NUMBER
CONSTRAINT TICKET_CK2
CHECK(1 = CASE TICKET_TYPE
WHEN 1 THEN CASE
WHEN SEATING IS NULL
THEN 1
ELSE 0
END
WHEN 2 THEN CASE
WHEN SEATING IS NULL
THEN 0
ELSE 1
END
WHEN 3 THEN CASE
WHEN SEATING IS NULL
THEN 1
ELSE 0
END
END),
REFUNDABLE_INDC CHAR(1)
NOT NULL
CONSTRAINT TICKET_CK3
CHECK(REFUNDABLE_INDC = CASE TICKET_TYPE
WHEN 1 THEN 'N'
WHEN 2 THEN 'Y'
WHEN 3 THEN 'N'
END),
FOOD CHAR(1)
NOT NULL
CONSTRAINT TICKET_CK4
CHECK(FOOD = CASE TICKET_TYPE
WHEN 1 THEN 'N'
WHEN 2 THEN 'N'
WHEN 3 THEN 'Y'
END),
DRINK CHAR(1)
NOT NULL
CONSTRAINT TICKET_CK5
CHECK(DRINK = CASE TICKET_TYPE
WHEN 1 THEN 'N'
WHEN 2 THEN 'N'
WHEN 3 THEN 'Y'
END));
Here CHECK constraints are used to ensure that only the appropriate fields are filled in, based on the ticket type.
Best of luck.

Joining 3 tables in Oracle

I need to join three tables in Oracle; I have code but I am not sure if it is totally right.
FROM DISTRICT D1
JOIN EMPLOYEE E1 ON D1.DISTRICT_ID = E1.DISTRICT_ID
JOIN TOTAL_PAB T1 ON E1.EMP_ID = T1.EMP_ID
I need to join the table DISTRICT, EMPLOYEE, AND TOTAL_PAB.
Where do the primary and foreign keys go in this join table statement?
Primary key for EMPLOYEE is EMP_ID and FK is DISTRICT_ID.
Primary key for DISTRICT is DISTRICT_ID and FK is SUPERINTENDENT_ID.
Primary key for TOTAL_PAB is PAB_ID and FK is EMP_ID.
The query seems legit, but you should give us some more informations for a better answer.
Generally, it's not important if a field is key or not: the important thing is that ONLY fields in "ON" part of the join statement will be used for matching rows.

Oracle Insert all data from another table contain duplicates how to avoid

have two tables A and B both same structure except B has one addition extra column inserting as "null". I need to Retain all data from A in B when I insert like below query it is inserting duplicate values because of that getting "primary Key violation error" when I try to create the "CONSTRAINT PK_Details_A PRIMARY KEY" Please help on this to avoid duplicate values while inserting the records.
Thanks in advance.
Insert into tableB(
id, effectiveDate, endDate
,startDate, Type, salary
,baseSalary, Amount, Amount1
,currency, Percentage, Salary
,Notional
)
select id, effectiveDate, endDate
,startDate, Type, salary
,baseSalary, Amount, Amount1
,currency, Percentage, Salary,null
from tableA;
EDIT
Primary key definition for B copied from comment below:
ALTER TABLE B
ADD CONSTRAINT PK_B
PRIMARY KEY ( oid)
USING INDEX ( CREATE UNIQUE INDEX PK_B ON B ( oid )

How do I perform a deletion of table entries from a full outer join?

What I have is several tables...two of them being:
CREATE TABLE Orders(
oid int NOT NULL,
rdate date,
sdate date,
cid int NOT NULL,
eid int NOT NULL,
PRIMARY KEY (oid),
FOREIGN KEY (cid) REFERENCES Customer(cid),
FOREIGN KEY (eid) REFERENCES Employee(eid));
CREATE TABLE PartOrder(
poid int NOT NULL,
pid int NOT NULL,
oid int NOT NULL,
PRIMARY KEY (poid),
FOREIGN KEY (pid) REFERENCES Part(pid),
FOREIGN KEY (oid) REFERENCES Orders(oid));
What I need to do is this:
Create and execute a query that deletes all PartOrder records for Orders for which the shipping date is in the past.
So, I came up with this...
DELETE
FROM (SELECT * FROM PartOrder FULL OUTER JOIN Orders ON partorder.oid=orders.oid)
WHERE sdate<sysdate;
This is giving me this error:
ORA-01752: cannot delete from view without exactly one key-preserved table
Can someone offer me some insight?
I'd write this as something like
DELETE FROM PARTORDER
WHERE POID IN (SELECT p.POID
FROM PARTORDER p
INNER JOIN ORDERS o
ON o.OID = p.OID
WHERE o.SDATE < SYSDATE);
Best of luck.

Resources