Where SQL column value not found in other column - sql

I've read similar questions and I think I am doing it correct, but I just wanted to make sure my SQL is correct. (Still new to SQL)
I have 2 different tables
Students
id, name, address
Staff
id, name, address
I need to find the total number of students (who are not also staff)
SO I have the following SQL
create view nstudents as
select students.id
from students
LEFT JOIN staff ON staff.id = students.id;
Then I run the count(*) on the view.
Can someone confirm my SQL is correct or is there better way to do it?

Your LEFT JOIN doesn't eliminate students who are also staff, but it could be useful in achieving your goal. LEFT JOIN provides you with all results from the left table and matching results from the right table, or NULL results if the right table doesn't have a match. If you do this:
select count(*)
from students
LEFT JOIN staff ON staff.id = students.id
WHERE staff.id IS NULL;
I expect you'll get what you're looking for.

You might find it more natural to do something like this:
create view nstudents as
select s.id
from students s
where not exists (select 1 from staff st where st.id = s.id) ;
This should have the same performance as the left join.

Related

sql join tables IS NOT

I need to get the data of all teachers who gives a course but does not have an assignement. I tried using inner or left join so if the name of the teacher is not in the table of the assignments it will show the data. If the name of the teacher is in the table of assignments it must not show the data. But I could not get it working.
What am I doing wrong?
select teachers.nameteacher, courses.namecourse, courses.codecourse
from teachers
inner join courses
on teachers.codecourse = courses.codecourse
left join assignments
on assignments.nameteacher = teachers.nameteacher
where teachers.nameteacher IS NULL
filter should be from assignments table
SELECT t.nameteacher,
c.namecourse,
c.codecourse
FROM teachers t
INNER JOIN courses c
ON t.codecourse = c.codecourse
LEFT JOIN assignments a
ON a.nameteacher = t.nameteacher
WHERE a.nameteacher IS NULL --should be assignments
Note : start using alias names to make the query more readable
The easy (and efficient) way, if you are using PostgreSQL or Microsoft SQL Server is to say:
select
a.nameteacher,
c.namecourse,
c.codecourse
from
(
select nameteacher from teachers
except
select nameteacher from assignments
) a
join teachers b
on a.nameteacher = b.nameteacher
join courses c
on b.codecourse = c.codecourse;
If you are using Oracle change "except" to "minus".
If you are using SQLite or MySQL you need to use one of the other suggestions because these don't support except or minus.

Oracle SQL, Can't Figure Out Left Join

I have 2 tables:
Person table with column person_id
Employee table with columns emp_type = full or part
I need a query that returns everyone in Person, but exclude full time employees. What I'm struggling with is not all Persons are necessarily in Employee table.
Can someone help me out? Thanks!
You can try code below, but you didn't give us your tables structure so I can only guess what do you mean here.
select *
from person p
left join employee e on p.person_id = e.person_id
where p.emp_type <> 'full'
Since you didn't post your full query or table structure information, you'll need to make adjustments. But using a not exists clause is probably the most straight forward way of doing this.
select p.*
from person p
where not exists (select null
from employee e
where e.person_id = p.person_id
and e.emp_type = 'full')

EXISTS Syntax in sql?

I have two tables:
students(id, name, school_id)
schools(id, name)
I'm trying to use EXISTS in order to learn if there are any students that go to specific school, say "Harvard" for example. I know that EXISTS is used after WHERE but I'm wondering if I can do this:
SELECT EXISTS
(SELECT *
FROM students st, schools sch
WHERE st.school_id=sch.id AND sch.name="Harvard");
Is this query correct? I am working on MySQL Workbench and I don't get an error. But I don't know if it does what it's supposed to do.
If it's not, then what should I change? I just want to know if it's correct and if I can use this syntax in the future.
Note that the desired result is either yes or no (1 or 0).
How do I get this result?
Sorry if my question was unclear, I can edit it again if you still don't understand.
You could just get the count, then you would know if any exist - and if so, how many...
SELECT COUNT(*)
FROM students st, schools sch
WHERE st.school_id=sch.id AND sch.name="Harvard"
The EXISTS keyword is normally used as a pre-condition... i.e. "if not exists, then add this..."
This is a simple Select with a Join.
SELECT *
FROM Students S
JOIN Schools SC
ON S.School_id = SC.id
Where SC.Name = 'Harvard'
This will give you all the rows for the students that go to Harvard, if any. If you want to do a count you can do SELECT COUNT(*) instead or limit which columns are returned by indicating the specific columns in the SELECT statement
This will give you student names that go to Harvard. If you wish to see how many students learn at Harvard replace st.name with count(*).
Note that it doesn't matter what you put in SELECT list inside EXISTS statement, so choosing a constant value provides better performance than selecting columns.
SELECT
st.name
FROM
students st
WHERE
EXISTS(
SELECT 1 FROM schools s WHERE s.name= 'Harvard' AND s.id = st.school_id)
OR
SELECT
st.name
FROM
students st
INNER JOIN schools s ON
st.school_id = s.id
WHERE
s.name = 'Harvard'
Additional note: Code below would only yield result either true or false.
SELECT EXISTS ( <query> )
This means that below query would return true if there are any students that learn at Harvard.
SELECT EXISTS (
SELECT 1
FROM students st
INNER JOIN schools s ON st.school_id = s.id
WHERE s.name = 'Harvard' )

Select where and where not

I have a table containing lessons that I called "cours" (french) and I have several cours inside and I have linked them to students with a table between them to see if they go to the lessons or not.
I would like to return data with the SELECT and the data that are NOT select.
So, If one student follow 3 courses of 5, I would like to return the 3 courses that he follow and the 2 courses that he doesn't follow.
Is there a way to do it ?
This will vary based on your RBDMS, but something similar to the following should work:
SELECT
s.Name,
l.Name,
CASE WHEN sl.StudentID IS NULL
THEN 'Not Follows'
ELSE 'Follows'
END AS Status
FROM
Student s
CROSS JOIN Lessons l
LEFT JOIN Student_Lessons sl
ON s.ID = sl.StudentID
AND l.ID = sl.LessonID
this is an outer join. if you identify your database engine (which may have specific outer join syntax) and your schema, then you can get some help with the actual SQL.

Three tables join given me the all combination of records

When i written the query like the following.. It's written the combination of all the records.
What's the mistake in the query?
SELECT ven.vendor_code, add.address1
FROM vendor ven INNER JOIN employee emp
ON ven.emp_fk = emp.id
INNER JOIN address add
ON add.emp_name = emp.emp_name;
Using inner join, you've to put all the links (relations) between two tables in the ON clause.
Assuming the relations are good, you may test the following queries to see if they really make the combination of all records:
SELECT count(*)
from vendor ven
inner join employee emp on ven.emp_fk = emp.id
inner join address add on add.emp_name = emp.emp_name;
SELECT count(*)
add.address1
from vendor ven, employee emp, address add
If both queries return the same result (which I doubt), you really have what you say.
If not, as I assume, maybe you are missing a relation or a restriction to filter the number of results.