Oracle 00904 error - sql

I am getting this error when trying to upload this script to Oracle. Does it have to do with my insert commands?
ALTER SESSION SET NLS_DATE_FORMAT = 'MM/DD/YYYY';
CREATE TABLE EMPLOYEE(
EMPLOYEE_ID NUMBER (15) PRIMARY KEY,
FIRST_NAME VARCHAR2(15) NOT NULL,
LAST_NAME VARCHAR2(15) NOT NULL,
);
INSERT INTO EMPLOYEE VALUES ('1001', 'JOHN', 'SMITHSON');
INSERT INTO EMPLOYEE VALUES ('1002', 'WILL', 'SMITH');
INSERT INTO EMPLOYEE VALUES ('1003', 'JASON', 'BOURNE');
INSERT INTO EMPLOYEE VALUES ('1004', 'RANDY', 'MARSH');
INSERT INTO EMPLOYEE VALUES ('1005', 'ANGELA', 'CARTMAN');
INSERT INTO EMPLOYEE VALUES ('1006', 'JANE', 'DOE');
INSERT INTO EMPLOYEE VALUES ('1007', 'MARY', 'JONES');

you have a extra , at the end of create table
LAST_NAME VARCHAR2(15) NOT NULL, -- remove ,
);
the varchar to number conversion works but better to give data in number for the first column

You shouldn't be putting apostrophes around your numbers. Try it without them.

Related

How to list total number of scholarships per department in SQL

I have 2 tables that look like this where I want to query how many scholarships (from Tuition table) each department (from Student table) has distributed:
I am thinking a join is necessary but am not sure how to do so.
Create tables
create table students (
sid int auto_increment primary key,
name varchar(100),
email varchar(100),
department varchar(100)
);
create table tutions (
id int auto_increment primary key,
sid int,
cost int,
scholarships int,
duedate timestamp default current_timestamp
);
Sample data
insert into students (name, email, department)
values
('John Doe', 'john#abc.xyz', 'B'),
('Jane Doe', 'jane#abc.xyz', 'A'),
('Jack Doe', 'jack#abc.xyz', 'C'),
('Jill Doe', 'jill#abc.xyz', 'B');
insert into tutions (sid, cost, scholarships)
values
(1, 1000, 2),
(2, 1000, 1),
(3, 1000, 7),
(4, 1000, 2);
Query (department-wise total scholarships)
SELECT department, sum(scholarships) as scholarships
FROM students s
JOIN tutions t ON s.sid = t.sid
GROUP BY department
Output
Running SQL Fiddle
Not sure It's something you want? And not sure scholarships is a number or name of scholarship? So I doubt it's a name as varchar string type.
### dummy record
CREATE TABLE students (
psu_id INTEGER PRIMARY KEY,
firstname VARCHAR NOT NULL,
lastname VARCHAR NOT NULL,
email VARCHAR NOT NULL,
department VARCHAR NOT NULL
);
CREATE TABLE tuition (
tuition_id INTEGER PRIMARY KEY,
student_id INTEGER NOT NULL,
semeter_cost INTEGER NOT NULL,
scholarships VARCHAR NOT NULL,
due_date DATE NOT NULL
);
INSERT INTO students VALUES (1, 'John', 'Hello', 'Jonh#email.com', 'Engineering');
INSERT INTO students VALUES (2, 'Bella', 'Fuzz', 'Bella#email.com', 'Computer');
INSERT INTO students VALUES (3, 'Sunny', 'World', 'Sunny#email.com', 'Science');
INSERT INTO tuition VALUES (1, 1, 4000, 'first_class_en', '2022-05-09' );
INSERT INTO tuition VALUES (2, 2, 3000, 'nobel', '2022-05-09' );
INSERT INTO tuition VALUES (3, 3, 5000, 'hackathon', '2022-05-09' );
INSERT INTO tuition VALUES (4, 1, 4500, 'second_class_en', '2022-05-09' );
-----------------
### query
SELECT s.department, count(t.scholarships)
FROM students s
JOIN tuition t
ON s.psu_id = t.student_id
GROUP BY s.department
### output
department, total_scholarships
Computer|1
Engineering|2
Science|1

AVG() inside LISTAGG()

I need to group two columns, one of them with an average, AVG() inside an LISTAGG().
I have the following code:
CREATE OR REPLACE VIEW countryTimes AS
SELECT
LISTAGG(claOL.odCode||'-'||(AVG(claOL.timeCla) GROUP BY(claOl.timeCla))) WITHIN GROUP (ORDER BY c.cCode) AS ProvaTempsMig,
c.cDescription AS País,
c.cCode AS CodiPaís
FROM countries c
JOIN athletes a ON c.cCode = a.country
JOIN classificationOL claOL ON a.idCode = claOL.idAth;
But this throws this error:
ORA-00907: missing right parenthiesis erecho 00907. 00000 - "missing right parenthesis" *Cause: *Action:
I'm using Oracle.
UPDATE:
What I need to do is create a view where appears cCode, cDescription and a last column with the AVG of all the times for a single country. So I need to create from multiple rows, a single row for each country.
Code:
CREATE TABLE Countries (
cCode VARCHAR(5) NOT NULL,
cdescription VARCHAR(100) NOT NULL,
CONSTRAINT couPK PRIMARY KEY (cCode)
);
CREATE TABLE athletes (
idCode NUMBER NOT NULL,
Name VARCHAR(200) NOT NULL,
Surname VARCHAR(200) NOT NULL,
country VARCHAR(5) NOT NULL,
CONSTRAINT athPK PRIMARY KEY (idCode),
CONSTRAINT countryFK FOREIGN KEY (country) REFERENCES Countries (cCode)
);
CREATE TABLE olympicDisciplines (
oCode VARCHAR(10) NOT NULL,
odName VARCHAR(200) NOT NULL,
discipline VARCHAR(200) NOT NULL,
CONSTRAINT olympicPK PRIMARY KEY (oCode)
);
CREATE TABLE classificationOL(
idAth NUMBER NOT NULL,
odCode VARCHAR(10) NOT NULL,
timeCla INTEGER,
CONSTRAINT classifPK PRIMARY KEY (idAth, odCode),
CONSTRAINT claAthFK FOREIGN KEY (idAth) REFERENCES athletes (idCode),
CONSTRAINT claDFK FOREIGN KEY (odCode) REFERENCES olympicDisciplines (oCode)
);
UPDATE 2:
Data:
INSERT INTO Countries VALUES ('UK', 'United Kingdom');
INSERT INTO Countries VALUES ('AND', 'Andorra');
INSERT INTO Countries VALUES ('FR', 'France');
INSERT INTO athletes VALUES (1, 'Jack', 'Johnson', 'UK');
INSERT INTO athletes VALUES (2, 'Pau', 'Márquez', 'AND');
INSERT INTO athletes VALUES (3, 'Pierre', 'Dubois', 'FR');
INSERT INTO athletes VALUES (4, 'Christophe', 'Dubois', 'FR');
INSERT INTO athletes VALUES (5, 'Adolphe', 'Moreau', 'FR');
INSERT INTO olympicDisciplines VALUES ('ATH', 'Athletics', 'Athletics');
INSERT INTO olympicDisciplines VALUES ('CYC', 'Cycling', 'Cycling');
INSERT INTO olympicDisciplines VALUES ('CCC', 'Cycling CC', 'Cross Country Cycling');
INSERT INTO classificationOL VALUES (1, 'ATH', 120);
INSERT INTO classificationOL VALUES (2, 'ATH', 119);
INSERT INTO classificationOL VALUES (3, 'CCC', 38);
INSERT INTO classificationOL VALUES (4, 'CCC', 37);
INSERT INTO classificationOL VALUES (5, 'ATH', 122);
Reading your first UPDATE, if you're allowed to, you can transform your tables to object to solve your necessity, instead of using LISTAGG(). I'll show you:
CREATE TYPE average AS OBJECT(
name VARCHAR(200),
avgerageTime NUMBER);
CREATE TYPE results AS TABLE OF average;
CREATE TYPE countriesResults AS OBJECT(
cName VARCHAR(100),
cCode VARCHAR(5),
classifications results
);
CREATE VIEW countriesAverages OF countriesResults
WITH OBJECT OID (coName)
AS
SELECT c.cdescription, c.ccode,
CAST (MULTISET (SELECT
olympicDisciplines.name, avg(classificationOL.timeCla)
FROM athletes a, countries, classificationOL, olympicDisciplines
WHERE countries.cCode = c.cCode
AND a.idCode = classificationOL.idAth
AND a.country = countries.cCode
AND olympicdisciplines.oCode = classificationOL.oCode
GROUP BY olympicdisciplines.odName) AS results )
FROM countries c;

Get value from table to use it in insert

I suppose this question was already asked somewhere here, but I have no idea how to name (and look for) it correctly.
The database:
CREATE TABLE department (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(100) NOT NULL UNIQUE
);
CREATE TABLE employee (
id INTEGER PRIMARY KEY AUTOINCREMENT,
department_id INTEGER NOT NULL,
chief_id INTEGER,
name VARCHAR(100) NOT NULL UNIQUE,
salary INTEGER NOT NULL,
FOREIGN KEY (department_id) REFERENCES department (id),
FOREIGN KEY (chief_id) REFERENCES employee (id)
);
INSERT INTO department (name) VALUES ('sales'), ('it'), ('management');
INSERT INTO employee (department_id, chief_id, name, salary) VALUES
(3, NULL, 'Owner', 1000000),
(2, 1, 'Team manager', 9000),
(2, 3, 'Senior dev #1', 7000),
(2, 3, 'Senior dev #2', 7000);
Now in insert I should calculate chief_id on my own, but I'm curious if there is a possibility to get id by name, something like
SELECT id FROM employee WHERE name = 'Owner'
and use this value instead of hardcoded id in insert.
I've tried putting select statement instead of id but that does not work.
I am using SQLite.
You can do it with a subquery as yours, but the data has to be in the table before you can select it. Otherwise the subquery returns null. So you need to break the one INSERT into multiple INSERTs.
INSERT INTO employee (department_id, chief_id, name, salary) VALUES
(3, NULL, 'Owner', 1000000);
INSERT INTO employee (department_id, chief_id, name, salary) VALUES
(2, (SELECT id FROM employee WHERE name = 'Owner'), 'Team manager', 9000);
INSERT INTO employee (department_id, chief_id, name, salary) VALUES
(2, (SELECT id FROM employee WHERE name = 'Team manager'), 'Senior dev #1', 7000),
(2, (SELECT id FROM employee WHERE name = 'Team manager'), 'Senior dev #2', 7000);
But note, that the subquery must return only one row. So the column you're checking in it's WHERE clause must contain unique values. Usually a name is not unique, there are a lot of John Smith. Usually the ID is the unique identifier. So in a general inserting the ID directly is the right approach.

Why is my sql query returning no records?

Schema:
created table dept
CREATE table dept
(dept_id varchar (20) default 'department' NOT NULL,
locat varchar (25) default 'location' NOT NULL,
nme varchar (20) default 'name' NOT NULL);
inserting values
INSERT INTO dept(dept_id, locat, nme)
VALUES (1, 'dublin', 'payroll');
INSERT INTO dept(dept_id, locat, nme)
VALUES (2, 'galway', 'manufacturing');
INSERT INTO dept(dept_id, locat, nme)
VALUES (3, 'cork', 'sales');
created table emp
create table emp
(emp_id varchar (20) default 'id' NOT NULL,
NME varchar (20) default 'name' NOT NULL,
job_title varchar (25) default 'job' NOT NULL,
HIRE_DATE DATE,
SALARY INT (25) default '0' NOT NULL,
dept_id varchar (20) default 'dept' NOT NULL);
inserting values
INSERT INTO emp
VALUES (123, 'byrne', 'clerical', DATE ('2012-06-12'), 28000, 1);
INSERT INTO emp
VALUES (124, 'barry', 'operater', DATE ('11-07-11'), 33000,2);
INSERT INTO emp
VALUES (125, 'hynes', 'senior_operator', DATE ('26-09-13'), 36500,2);
INSERT INTO emp
VALUES (126, 'WILLIAMS', 'manager', DATE ('30-10-13'), 51000,3);
THE FOLLOWING QUERY IS RETURNING NO RECORDS
SELECT NME FROM emp
where HIRE_DATE between ('01-01-10') AND ('01-01-14');
How to change the code to get the desired output.
You proper date formats. In Oracle, you can introduce constants with the date keyword:
INSERT INTO emp (emp_id, NME, job_title , HIRE_DATE, SALARY, dept_id)
VALUES (123, 'byrne', 'clerical', DATE '2012-06-12', 28000, 1);
INSERT INTO emp (emp_id, NME, job_title , HIRE_DATE, SALARY, dept_id)
VALUES (124, 'barry', 'operater', DATE '2011-07-11', 33000, 2);
INSERT INTO emp (emp_id, NME, job_title , HIRE_DATE, SALARY, dept_id)
VALUES (125, 'hynes', 'senior_operator', DATE '2013-09-26', 36500, 2);
INSERT INTO emp (emp_id, NME, job_title , HIRE_DATE, SALARY, dept_id)
VALUES (126, 'WILLIAMS', 'manager', DATE '2013-10-30', 51000, 3);
select NME
from emp
where HIRE_DATE between date '2010-01-01' and date '2014-01-01';
I thought 2-digit years when out in 1999. Oracle might not be interpreting two-digit years the same way that you do.
Also, include the column list when doing an insert.

SQL ORA-00907 missing right parenthesis?

So I am brand new to sql, and I was dabbling with creating a basic table to add and query data from. I am trying to create a table, but I keep getting an "ORA-00907 missing right parenthesis" error on the first part of the script, and I am not sure why. Here is my code:
CREATE TABLE Payroll
(
Identification_Number INTEGER(10),
Full_Name VARCHAR2(20) NOT NULL,
Position VARCHAR2(20) NOT NULL,
Salary INTEGER(20) NOT NULL
);
INSERT INTO Payroll (Identification_Number, Full_Name, Position, Salary) VALUES (1476563, 'Bob Smith', 'CEO', 6000000);
INSERT INTO Payroll (Identification_Number, Full_Name, Position, Salary) VALUES (1892345, 'Brian Smith', 'President', 5000000);
INSERT INTO Payroll (Identification_Number, Full_Name, Position, Salary) VALUES (1234567, 'Ron Smith', 'Vice President', 4000000);
SELECT * FROM Payroll;
Any suggestions?
Change your script as:
CREATE TABLE Payroll
(
Identification_Number NUMBER(10),
Full_Name VARCHAR2(20) NOT NULL,
Position VARCHAR2(20) NOT NULL,
Salary NUMBER(20) NOT NULL
);