Performance table:
PerformanceId SingerId MovieId NumberofSongs
1 1 1 2
2 3 1 4
3 2 2 6
4 4 5 3
5 5 5 3
6 2 6 2
7 4 6 5
8 6 4 6
9 6 3 3
10 4 3 4
Singer table:
SingerId SingerName City DOB Gender
1 A Hyderabad 14-Apr-65 M
2 B Chennai 25-May-84 M
3 C Bangalore 14-Sep-78 F
4 D Hyderabad 17-Jan-70 M
5 E Hyderabad 18-Mar-87 F
6 F Bangalore 23-Aug-75 F
Movie table:
MovieId MovieName ReleaseDate
1 AAA 12-Jan-15
2 BBB 19-Sep-12
3 CCC 23-Jul-10
4 DDD 06-Oct-01
5 EEE 08-Nov-05
6 FFF 18-Apr-99
7 GGG 07-Aug-12
I would need to list the MovieId, MovieName in which both Male and Female singers are performed
(list the movieid, moviename in which male and femail singer ie both singer are performed in one movie)
Hi guys please help me out with this query i tried i am not getting exact query
Here's my query:
select * from movies a inner join performance b
on a.movie_id=b.movie_id where b.singer_id in
(select singer_id from singer where gender = 'F') c inner join
(SELECT SINGER_ID FROM SINGER WHERE gender = 'M') d
on c.singer_id=d.singer_id;
First create a view "MOVIE_ANALYSIS" where you'll have a list of all movies and if they've mixed singers or not:
CREATE VIEW MOVIE_ANALYSIS AS SELECT
M.MOVIEID ,
M.MOVIENAME,
(COUNT(DISTINCT S.GENDER) > 1) AS MIXED
FROM MOVIE M
INNER JOIN PERFORMANCE P ON P.MOVIEID = M.MOVIEID
INNER JOIN SINGER S ON S.SINGERID = P.SINGERID
GROUP BY M.MOVIEID ;
Then you'll get your final result with this query:
SELECT * FROM MOVIE_ANALYSIS WHERE MIXED IS TRUE ;
The reason I used an intermediate view is that in several SQL engines, you cannot use the computed "mixed" attribute directly in the same query with a group by. It'll keep insisting that mixed column is missing.
Validated and test on H2. I did not test on Oracle, as I've no access to it.
What you want here is the INTERSECT statement (using Oracle):
select movieId
from performance a
where exists (select 1
from singer b
where A.singerID = b.singerID
and b.gender = 'F')
intersect
select movieId
from performance a
where exists (select 1
from singer b
where A.singerID = b.singerID
and b.gender = 'M');
Then you just join the movie IDs you get back to the Movie table.
INTERSECT will only bring back IDs that are common to both queries (or however many you use).
Related
I have three tables :
field:
f_id
f_start
f_end
1
10
20
2
15
25
3
5
10
person :
p_id
p_name
1
Roger
2
John
3
Alicia
affect :
id
fk_field
fk_person
1
2
1
2
1
2
3
3
3
And I would like to select the dates and the names associated to. Like this
p_name
f_start
f_end
Roger
15
25
John
10
20
Alicia
5
10
I'm new to SQL and I don't know if i have to use JOIN or not... Thanks
You must join all 3 tables on their related columns:
SELECT p.p_name, f.f_start, f.f_end
FROM person p
INNER JOIN affect a ON a.fk_person = p.p_id
INNER JOIN field f ON f.f_id = a.fk_field;
Depending on your requirement you may need LEFT instead of INNER joins, but for this sample data the INNER joins will do.
I have 3 table
driver
id
first name
last_name
age
1
Joe
doe
26
2
John
smith
31
...
...
...
...
Location
id
name
zipcode
country
1
London
250 329
UK
2
NY
00501
USA
...
...
...
...
Travel
id
Person_id
location_id
nb_passenger
1
1
1
2
2
1
1
4
3
2
2
3
4
1
2
2
5
2
1
3
...
...
...
...
I'm looking to create a view to get the total number of passengers by destination and by driver, but it's taking the same row multiple times
I tried something like that but it didn't work
SELECT location.id AS location_id,
location.name AS location_name,
d.id AS driver_id,
d.name AS driver_name,
sum(tr.passenger) as passenger_count
FROM location
LEFT JOIN travel tr_0 ON location.id = tr_0.location_id
LEFT JOIN driver d ON tr_0.driver_id = d.id
LEFT JOIN travel tr ON location.id = tr.location_id AND tr.driver_id = d.id
GROUP BY location.id, location.name,...;
I'm sure it's simple but I'm not on the right way
Hi I have a course table
course_id name type
1 Arthematic Maths
2 Geometry Maths
3 Chemistry Science
4 Biological Science
5 Hisotry Social
6 Independence Social
more records like this
And student table
student_id name
101 David
102 Tony
103 Skye
104 Nicole
105 Ossof
And a student_course many to many join table
id student_id course_id
1 102 2
2 102 3
3 101 1
4 101 2
5 101 3
6 103 2
7 103 5
8 104 3
9 105 1
10 104 5
I am trying to find all the students who have both Maths and Science course types for a given course IDs. Means I need to find students who have atleast one Maths type course and atleast one Science course type for given input of course ids
I have written this query but this gives student ids for any student who either Maths or Science or both
select sc.student_id from student_course sc left join course c on sc.course_id = c.id
where c.type = 'Maths' OR c.type = 'Science' and c.id IN (1,3,5)
group by sc.student_id having count(sc.student_id) >= 2
In this case, it would be better to use in operator to avoid logical mistakes related to parentheses, also you should use count with distinct to avoid counting the same types.
select sc.student_id
from student_course sc inner Join course c on sc.course_id = c.id
where c.type In ('Maths','Science') and c.id in (1,3,5)
group by sc.student_id
having Count(distinct c.type) = 2
db<>fiddler
Result:
student_id
101
I need to query a name(s) from the Officials table, but exclude that name if the person has the day blocked.
For example, if Sam has blocked 8/21/2021 and 9/11/2021, he should not be selected if the corresponding dates are selected from the Games table. Sam should show up if 9/18/2021 is selected, however. I have 3 tables:
Officials tbl
RefId Name
---------------------
1 Jack
2 Sam
3 Jane
Games tbl Blocks tbl
GameId GameDate BlockId RefId BlockDate
------------------------- ----------------------
1 8/21/2021 1 2 8/21/2021
2 9/11/2021 2 2 9/11/2021
3 9/18/2021 3 3 8/21/2021
Desired Output
----------------------------------
If Game 1 is selected: Jack
If Game 2 is selected: Jack and Jane
If Game 3 is selected: Jack, Sam and Jane
The only 2 tables that are related are the Officials table and Blocks table, with the RefId. I need to compare the BlockDate of Blocks table to GameDate of Games table. I have tried some sql language and this below is obviously not correct, but I'm looking for a way to accomplish what I want to do:
#GameDate datetime,
Select c.Id, c.Name
From Officials c
Where In c.Id And Blocks.BlockDate <> Games.GameDate)
You can do it with NOT EXISTS:
SELECT o.*
FROM Officials o
WHERE NOT EXISTS (
SELECT 1
FROM Blocks b INNER JOIN Games g
ON g.GameDate = b.BlockDate
WHERE b.RefId = o.RefId AND g.GameId = ?
);
See the demo.
Let's say I have two tables. A students table and an observations table. If the students table looks like:
Id Student Grade
1 Alex 3
2 Barney 3
3 Cara 4
4 Diana 4
And the observations table looks like:
Id Student_Id Observation_Type
1 1 A
2 1 B
3 3 A
4 2 A
5 4 B
6 3 A
7 2 B
8 4 B
9 1 A
Basically, the result I'd like from the query would be the following:
Student Grade Observation_A_Count
Alex 3 2
Barney 3 1
Cara 4 2
Diana 4 0
In other words, I'd like to gather data for each student from the students table and for each student count the number of A observations from the observations table and tack that onto the other information. How do I go about doing this?
This is a simple join and aggregate:
select
a.Student,
a.Grade,
count(b.Id) as Observation_A_Count
from
Student a left join
Observations b on a.Id = b.Student_Id
group by
a.Student,
a.Grade
order by
1
Or, you can use a correlated subquery:
select
a.Student,
a.Grade,
(select count(*) from observations x where x.Student_Id = a.Id) as Observation_A_Count
from
Student a
order by
a.Student
You can join the table with a specific condition, by doing this you can have a field for Observation_B_Count and Observation_C_Count, etc.
SELECT Student.Student, Student.Grade, COUNT(Observation_Type.*) AS Observation_A_Count
FROM Student
LEFT JOIN Observations ON Observations.Student_ID = Student.Student_ID AND Observations.Observation_Type = 'A'
GROUP BY Student.Student, Student.Grade