How to get value from one table based on distinct values from another table? - sql

I'm trying to write sql query which return me subject_id(result table) where primary_skill(student table) is unique.
Result table has column (student_id, subject_id, mark)
My query:
SELECT r.subject_id
FROM result r
JOIN student s ON r.student_id = s.student_id
WHERE s.primary_skill IN (SELECT DISTINCT primary_skill
FROM student)
GROUP BY 1;
I have this result:
subject_id
1
2
3
4
5
6
7
8
9
10
1001
But I should return only id 1001, because only this subject has unique student primary_skill, in other ids primary skill are repeated.
What am I doing wrong? How it improve?

Please try following:
select result.subject_id from student
join result on student.id =result.student_id where
student.primary_skill in
(select primary_skill from student group by primary_skill having COUNT(*)=1)

If I understand this right, you want results for students only having one skill. You can use GROUP BY and a HAVING clause checking for the count of skill being equal to one for this.
SELECT r.subject_id
FROM result r
INNER JOIN (SELECT s.student_id
FROM student s
GROUP BY s.student_id
HAVING count(DISTINCT s.primary_skill) = 1) x
ON x.student_id = r.student_id;

Related

How to get the unmatched records from two tables using Joins

I have two tables one is teacher and another is Department which is mentioned below.
Teacher Table
Id Name
1 xyz
2. Gjd
3. Dftr
4 dhdk
Department Table
Id Name EMPID
1 SQL. 2
2. PHP. 4
3. JAVA. 1
4 PEARL. 5
QUESTION
i want those records of teacher which are not link with any Department.
you can use following statement using left join then filter Teacher that not matched
SELECT t.*
FROM Teacher t
left join Department d on d.EMPID = t.Id
where d.id is null
SELECT * FROM teachers WHERE
id NOT IN (SELECT DISTINCT EMPID FROM departments) ;
Hope this helps.!!
you can do it by inner query..
select * from teacher where id not in (select empid from department);

SQL Select entries where none of the entities have a value in a particular column

I have a table of data which has students and their subject results in it. The students will appear multiple times, once for each subject they have a result for.
**tableID,studentID,lastName,firstName,subject,grade**
1,1a,Student1,Name1,English,A
2,1a,Student1,Name1,Maths,A
3,1a,Student1,Name1,Science,A
4,2a,Student2,Name2,English,A
5,2a,Student2,Name2,Maths,B
6,2a,Student2,Name2,Science,A
7,3a,Student3,Name3,English,A
8,3a,Student3,Name3,Maths,A
Using Microsoft Access SQL, how can I select only the students who have received an A for all of their subjects? E.g. In the above table, I only want to select all instances of Student1 and Student3, I don't want Student2 as they have not received all A's.
Get all students with grade A except students with any other grade
SELECT
studentID,lastName,firstName
FROM
(SELECT
studentID,lastName,firstName
FROM
result
WHERE
grade = 'A'
GROUP BY
studentID,lastName,firstName) GradeA
LEFT OUTER JOIN
(SELECT
studentID,lastName,firstName
FROM
result
WHERE
grade <> 'A'
GROUP BY
studentID,lastName,firstName) GradeOther
ON GradeA.studentId = GradeOther.StudentID AND GradeA.LAstName = GradeOther.LastName AND GradeA.FirstName = GradeOther.FirstName
WHERE
GradeOther.StudentID IS NULL
One way is using GROUP BY and HAVING:
select StudentId
from t
group by StudentId
having max(grade) = min(grade) and max(grade) = 'A';
I was able to get the results I want by using a sub-query:
SELECT studentID, lastName, firstName
FROM table
WHERE grade = "A"
AND studentID NOT IN (SELECT studentID FROM table WHERE grade <> "A" GROUP BY studentID)
GROUP BY studentID, lastName, firstName
This seems to exclude all students who received a result other than an A.

Sql Query Join in Oracle

I have Parent table and multiple child tables with foreign key constraint.
School Table
School ID EduDetails Genders Address_id EDUTYPE
1 2 M 3 FGN
And the child tables like
Education Details
EDU ID EducationType
2 Online
AKA Name
School Id AKA Name
1 Test School
1 School Test
Gender Table
Gender ID Gender Desc
M Male
I am using Left outer join for the parent and school table to fetch the results.
But My issue is, If AKA table has 5 counts matching the school Id and Gender table has only 1 records for that school Id.
So the results comes with 5 duplicate rows with school Information and also other child table information.
Is there any workaround to fix this issue. I tried using subquery and row_number over by function. But it is not working for me. Can anybody help me to solve this issue.
Thanks in advance for your time in looking this issue.
My required output should be like this
School_id AKA Name GenderDesc EductaionType
1 Test School Male Online
1 School Test
So I need to have Null values for the not matching records.
Since you want all the records in the AKA Name table, I've joined on that getting a Row_Number for each row. Then using that Row_Number, LEFT JOIN on the other tables.
SELECT S.SchoolId,
SA.AKAName,
G.GenderName,
ED.EducationType
FROM School s
JOIN
(SELECT SchoolId,
AKAName,
ROW_NUMBER() OVER (PARTITION BY SchoolId ORDER BY AKAName) rn
FROM SchoolAKA
) SA ON S.SchoolID = SA.SchoolId
LEFT JOIN
(SELECT EDUID,
EducationType,
ROW_NUMBER() OVER (ORDER BY EducationType) rn
FROM EduDetails
) ED ON S.EDUID = ED.EDUID AND SA.rn = ED.rn
LEFT JOIN
(SELECT GenderId,
GenderName,
ROW_NUMBER() OVER (ORDER BY GenderName) rn
FROM Genders
) G ON S.GenderId = G.GenderId AND SA.rn = G.rn
Here is the SQL Fiddle.
And here are the results:
SCHOOLID AKANAME GENDERNAME EDUCATIONTYPE
1 School Test Male Online
1 Test School (null) (null)

Help with query

I'm trying to make a query that looks at a single table to see if a student is in a team called CMHT and in a medic team - if they are I don't want to see the result.
I only want see the record if they're only in CMHT or medic, not both.
Would the right direction be using sub query to filter it out? I've done a search on NOT IN but how could you get to see check if its in more then 2 teams are not?
Student Team ref
1 CMHT 1
1 Medic 2
2 Medic 3 this would be in the result
3 CMHT 5 this would be in the result
So far I've done the following code would I need use a sub query or do a self join and filter it that way?
SELECT Table1.Student, Table1.Team, Table1.refnumber
FROM Table1
WHERE (((Table1.Team) In ('Medics','CMHT'))
This is Mark Byers's answer with a HAVING clause instead of a subquery:
SELECT Student, Team, ref
FROM Table1
GROUP BY Student
HAVING COUNT(Student) = 1
SELECT *
FROM students
WHERE NOT EXISTS
(
SELECT NULL
FROM students si
WHERE si.student = s.student
AND si.team = 'CMHT'
)
OR NOT EXISTS
(
SELECT NULL
FROM students si
WHERE si.student = s.student
AND si.team = 'Medic'
)
SELECT a.*
FROM Table1 a
INNER JOIN
( SELECT Student, COUNT(*) FROM Table1
GROUP BY Student
HAVING COUNT(*) = 1)b
ON (a.Student = b.Student)
how could you get to see check if its in 2 or more teams?
You can count the number of teams per student and then filter only those you want to see:
SELECT student FROM
(
SELECT student, COUNT(*) AS cnt
FROM Table1
GROUP BY student
) T1
WHERE cnt = 1
You can do it with outer join
select COALESCE(t1.Student, t2.Student) as Student,
COALESCE(t1.Team, t2.Team) as Team,
COALESCE(t1.ref, t2.ref) as ref
from
(select * from Student where Team = 'CMHT') t1
outer join
(select * from Student where Team = 'Medic') t2
on t1.Student = t2.Student
where
t1.Student is null or
t2.Student is null;

SQL issue,challenge

Say we have two entities:teacher and student.
each teacher has multiple student.
Now I want to:
query for at most 5 teachers,and for each teacher, no more than 10 of his student.
So far this can be done quite easily by:
select *,
(
select GROUP_CONCAT('<sid>',students.name,'</sid>') from students on
teachers.id=students.teacher limit 10
) as students
from teachers limit 5
But that's not the whole story yet.
AND
If anyone of the teachers has more than 10 students,should return true for that teacher,otherwise false
How to do this in SQL?
Pseudo SQL: one row of results for each of the 10 students for each of the 5 teachers
select t.teacher_id, s.student_id,
case when t2.count > 10 then 'true' else 'false' end
from
(select top 5 *
from teachers
order by teacher_id) t
join
(select top 10 *
from students s1 join teachers t1 on s1.teacher_id = t1.teacher_id
order by student_id) s
on t.teacher_id = s.teacher_id
join
(select teacher_id, count(*) as count
from teachers t join students s on t.teacher_id = s.teacher_id
group by teacher_id) t2
on t2.teacher_id = t.teacher_id
LINQ makes this super-easy
Use a subquery for every teacher selected.