Subquery in Insert - sql

I am trying to use subquery in insert query but i'm getting error. How can i solve this?
insert into classes_has_students (id,student_id,class_id)
values (
(select id from students where first_name = 'Subhan'),
(select id from classes where class_name = 'FSC')
)

You have an extra id in the columns list. Presumably, it is assigned automatically so you can leave it out:
insert into classes_has_students (student_id, class_id)
values ( (select id from students where first_name = 'Subhan'),
(select id from classes where class_name = 'FSC')
)
Otherwise, you need to give it a value:
insert into classes_has_students (id, student_id, class_id)
values ( 42,
(select id from students where first_name = 'Subhan'),
(select id from classes where class_name = 'FSC')
)

Related

How to insert new row without duplicating existing data

I want to insert rows in my table like so:
my columns are student,subject,class,teacher,level. Primary key is (student,subject). The table contains all the students, but the Math subject is missing for some of them, so I want to add it without duplicating the ones that already have it.
I've tried this but it gives me unique constraint violated:
insert into table (student,subject,class,teacher,level)
select a.student, 'math', null, null, null
from table a
where a.student in (select distinct student from table where subject not in 'math')
and (a.student,a.subject) not in (select student,subject from table);
I think you basically need select distinct:
insert into table (student, subject)
select distinct a.student, 'math'
from table a
where not exists (select 1
from table a2
where a2.student = a.student and
a2.subject = 'math'
);
One approach would be to use minus:
insert into course_students (student, subject)
select student, 'Math' from course_students
minus
select student, subject from course_students;
This would would need extending a little if you wanted to include other columns in the insert:
insert into course_students (student, subject, class, teacher, course_level)
select student, subject, '101', 'Naomi', 1
from ( select student, 'Math' as subject from course_students
minus
select student, subject from course_students );

sql previous row

I have a SQL question, typical :previous row, next row question BUT:
NOT USING rownum,lead or rankover these functions, only select and join,
Table: Student
Fields: Student_ID, Department, Start_Date
ex:
1,C, 2017-01-1
1,B, 2017-07-1
1,A, 2017-12-1
Expected Output:
Student_ID, Department, Start_Date, End_Date
ex:
1,C, 2017-01-1, 2017-07-01
1,B, 2017-07-1,2017-12-01
1,A, 2017-12-1, ...
End_Date is the start Date of the next record for the student ID
You could try this:
Data
create table student (
Student_ID int,
Department char(1),
Start_Date date
);
insert into student values (1, 'A', '2017-01-01');
insert into student values (1, 'B', '2017-01-01');
insert into student values (1, 'C', '2017-12-31');
SQL Server
select
student_id,
department,
start_date,
(select top 1 start_date
from student
where student_id = s.student_id
) as end_date
from student s
order by student_id, department;
Example: http://rextester.com/HLL58959
PostgreSQL and MySQL and SQLite
select
student_id,
department,
start_date,
(select start_date
from student
where student_id = s.student_id
limit 1) as end_date
from student s
order by student_id, department;
Example: http://rextester.com/XWUAZ90711

Inserting Data into Two Tables in one Query

Student Table
id|student_num|name|surname
Course Table
id|course_name
Student_course Table
course_id|student_id|mark
When I insert data into the Student Table (id, student_num, name, surname), the id should be inserted into Student_course Table, student_id column.
Assuming you want to insert the new student for all courses, then in Postgres you can do this:
with new_student as (
insert into student
(id, student_num, name, surname)
values
(1, 42, 'Dent', 'Arthur)
returning id
)
insert into Student_course (student_id, course_id)
select (select id from new_student),
id
from course;

Removing redundancies in sql query that contains subquery

Suppose we have a table with scheme
student(id (primary key), name, math_score, english_score)
I am trying to get student information (id and name) with highest rank (ordered by highest sum of math score and english score). There may be several student with tie, and we want all of them. The way I thought about doing this is to use subquery to get a table with sum of scores, then find ids, names that have highest sum.
SELECT s.id, s.name
FROM (SELECT s.id, s.name, s.math_score+s.english_score as sum
FROM student s) s
WHERE s.sum = (SELECT max(s.sum)
FROM (SELECT s.id, s.name, s.math_score+s.english_score as sum
FROM student s) s)
This works, but seems very redundant and not efficient.
I just started learning sql language, and I would appreciate some insight on this problem!
Use WITH TIES
create table #student(
id int primary key identity(1,1),
name varchar(50),
math_score decimal,
english_score decimal
)
insert into #student
values
('Tom', 90, 90),
('Dick', 70, 70),
('Harry', 80, 100)
select TOP(1) WITH TIES
id,
name,
math_score,
english_score,
math_score + english_score as ScoreRank
from #student
order by
math_score + english_score desc
Gives the answer:
id|name|math_score|english_score|ScoreRank
1|Tom|90|90|180
3|Harry|80|100|180
This should accomplish it, you're adding in an unnecessary step.
select id,
name,
math_score+english_score as total_score
from student
where math_score+english_score=(select max(math_score+english_score)
from student)
SELECT id, name, math_score+english_score as 'sum'
FROM student
Order by math_score+english_score DESC;

Insert random data into a table that has foreign key

I have a table "User" (idUser, name, departmentId) and another table "Department" (idDepartment, name).
I would like to insert random data into table User, but it would be necessary to consider only the departments previously inserted.
I think it would be something like:
INSERT INTO User (idUser, name, departmentId)
VALUES (seq_user.nextVal, 'random name', FK_RANDOM_DEPARTMENT);
How can I generate this 'random name' and only use departments that I have already inserted?
Thanks in advance!
INSERT INTO User
(idUser, name, departmentId)
VALUES
(seq_user.nextVal,
DBMS_RANDOM.STRING('L', 20), /*20 is a number of characters in a string*/
(SELECT * FROM (SELECT idDepartment FROM Department ORDER BY DBMS_RANDOM.VALUE) WHERE ROWNUM = 1)
);