How to insert new row without duplicating existing data - sql

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 );

Related

Populating relationship table randomly from two entity tables Postgresql

I'm attempting a simple E-R where the two entity sets are : Student & University each having about 200rows & the relationship to be "Applies" [so student applies to university]
I have the student table with a few data but the Primary Key being Student_ID
the University has Univeristy_Name as the PK;
now the relationship - "applies" - I have the student_ID & University_Name as FK & application_ID as PK
I have to populate this "applies" table containing about 10% chosen at random of the possible relationship, using one single INSERT statement & maybe a "random()" function. Does anyone know how do I go about populating the table using values from the other two tables randomly?
You would use:
insert into applies (student_id, university_name)
select s.student_id, u.university_name
from students s cross join
universities u
order by random()
limit 4000;
Alternatively, you can do this without sorting using:
insert into applies (student_id, university_name)
select s.student_id, u.university_name
from students s cross join
universities u
where random() < 0.1;
Note that this is an approximate 10% sample of the rows rather than an exact count.
You can cross join the two tables to get all combinations of student and university. Then number your rows in random order and keep those with a number <= the number of total rows divided by ten to keep 10% of those combinations:
insert into applies (student_id, university_name)
select student_id, university_name
from
(
select
s.student_id,
u.university_name,
row_number() over (order by random()) as rn,
count(*) over () as cnt
from student s
cross join university u
) randomized
where rn <= cnt / 10.0;
I replicated your case with
create table students (student_id serial primary key, name varchar);
create table university (University_Name varchar primary key);
insert into students (name) values ('Francesco');
insert into students (name) values ('Laura');
insert into students (name) values ('Christian');
insert into students (name) values ('Ugo');
insert into students (name) values ('Maria');
insert into students (name) values ('Antonietta');
insert into university values ('Bocconi');
insert into university values ('Universita di Pisa');
insert into university values ('Universita di Padova');
insert into university values ('Universita di Perugia');
If you don't have any limits in students applying for multiple universities, you could achieve the insert with
select * from students cross join university order by random() limit 3;
Where limit 3 displays only 3 rows

Inserting dynamic amount of rows based off Amount of IDS found from search

I am trying to insert into the table TAKES(ID, COURSEID, SEC_ID, SEMESTER, YEAR , GRADE) off all the students who have not taken a certain course.
I correctly get the IDS needed from the table with the call
select ID from student
where dept_name = 'Computer Science'
minus
select ID from takes
where course_id = 'CS-347';
then I go to actually insert it with these IDS that I have retrieved and all the other fields for insert are static.
insert into TAKES
SELECT ID,'CS-347' as COURSE_ID,1 as SEC_ID,'Spring' as SEMESTER,2021 as YEAR,NULL as GRADE
from student
where dept_name = 'Computer Science'
minus
select ID from takes
where course_id = 'CS-347';
I then get the an error:
Incorrect number of result columns.
I know that I am only pulling from the Student column, but I'm not sure how to work around this as in I have tried selecting the IDS individually and that didn't work either.
you can use this query instead :
insert into TAKES (column names)
SELECT
ID,
'CS-347' as COURSE_ID,
1 as SEC_ID,
'Spring' as SEMESTER,
2021 as YEAR,
NULL as GRADE
from
student
where
dept_name = 'Computer Science'
and ID NOT IN (select
ID
from
takes
where
course_id = 'CS-347');
when you use minus both side of operation need of return them same number of columns . also make sure you are inserting the right columns , better to mention column names

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;

how to write this SQL? specifics inside

Assume we have a table which records grades of all students of a class. There are two columns among others in the table: 1) student_id, 2) grades, The value of grades is a single letter which can be "A", "B", "C" or "F". How to write a SQL listing all student ids (one student per line) who has never got a "B" grade? Thanks.
PS: Assume we are using MySQL.
You would need a subquery to accomplish this. You'll return records from the table where the student_id is not in the list of students who have received a B.
select student_id, grades
from table_name
where student_id not in (select student_id from table_name where grade = 'B')
Use this and sorry, you need to define that student_id can be repeated in table
select student_id from table_name where grades in ('A','B','C')
and student_id not in(
select student_id from table_name where grades = 'B'
)

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)
);