I would like to return the follow question in SQL.
In which action movie play more female then male?
I got a table which movie_id/title/genre, a table with cast_id/gender.
And between this table a link table with movie_id and cast_id.
Can someone explain how to extract the data from a construction like this?
I came up with this so far
SELECT titel, geslacht, genre
FROM imdb.film
INNER JOIN imdb.cast ON cast.cast_id = film.film_id
You can join the three tables involved and group by title to check for the condition.
SELECT f.title
FROM imdb.film f
INNER JOIN imdb.cast c ON c.cast_id=f.film_id
INNER JOIN link_table l ON l.movie_id=f.movie_id and l.cast_id=c.cast_id
WHERE f.genre = 'ACTION'
GROUP BY f.title
HAVING SUM(c.gender = 'F') > SUM(c.gender = 'M')
Replace link_table in the query with the actual table name.
Related
I want to return the data of all the tables linked together via foreign keys when the tables are linked together in a chain. Is there a simple SQL command for this?
SAMPLE DATA: A entrance has floor_id fk to floors table, floor table has a building_id fk to buildings, buildings has a company_id fk to companies.
Can I get all the above data given just the entrance id?
Is there a more elegant way to do this then the following SQL:
SELECT * FROM floor_entrance
LEFT JOIN floor ON floor.id = (SELECT floor_id FROM floor_entrance WHERE id = {floor_entrance_id})
LEFT JOIN building ON building.id = (SELECT building_id FROM floor WHERE id =
(SELECT floor_id FROM floor_entrance WHERE id = {floor_entrance_id}))
LEFT JOIN company ON company.id = (SELECT company_id FROM building WHERE id =
(SELECT building_id FROM floor WHERE id =
(SELECT floor_id FROM floor_entrance WHERE id = {floor_entrance_id})))
WHERE floor_entrance.id = {floor_entrance_id}
I am looking to achieve a concise way to write this postgreSQL command.
DESIRED RESULTS: "LEFT JOIN ALL ON FOREIGN KEYS ACROSS THE WHOLE SCHEMA"?
I would simply do it like this
SELECT * FROM floor_entrance A
LEFT JOIN floor B ON A.floor_id = B.id
LEFT JOIN building C ON B.building_id = C.id
LEFT JOIN company D ON C.company_id = D.id
WHERE A.id = {floor_entrance_id}
There appears to be no one simple way to do this. However the answer by #Alexis.Rolland is a neat way to do this even though you must left join each table manually.
I have a main table M (Movies) and other tables L (Location), G (Genre), and S (Sub Genre). Each of the "other" tables are in a one to many relationship to table M, using.
I want to list all the Blu Ray titles and pull in their Location, Length (Time), Comments, Genre, and Sub Genre.
My query is:
SELECT L.Location, M.Title, M.Length, M.Comments, G.Genre, S.SubGenre
FROM ((L
INNER JOIN M ON M.Location = L.ID)
INNER JOIN G ON M.Genre = G.ID)
INNER JOIN SubGenre ON M.SubGenre = SubGenre.ID
ORDER BY M.ID
WHERE M.Type is "BluRay"
ORDER BY M.ID;
It gives me a subset of what the subset (26) of what the total number of records should be (447.)
1. Do I have the proper table relationships?
2. Do I really need the parentheses? (error without them)
3. How do I change my query to give me all the Location records, with the appropriate movie-related information?
4. What if I want to add additional tables?
The DB schema:
-- Note that Type and Length are in between square brackets, because those are reserved words.
-- Avoid use of reserved words with MovieType and MovieLength
SELECT
L.LocationName
, M.Title
, M.[Length]
, M.Comments
, G.GenreName
, S.SubGenreName
FROM Movies M
INNER JOIN Location L ON L.LocationID = M.LocationID
INNER JOIN Genre G ON G.GenreID = M.GenreID
INNER JOIN SubGenre S ON S.SubGenreID = M.SubGenreID
WHERE M.[Type] = 'BluRay'
ORDER BY M.MovieID
You need to JOIN on shared table columns.
For "How to change your query to give all Location records, with appropriate movie-related information" that depends on what you think is appropriate.
You should not need the parentheses. Unless you are using a SQL database I am not familiar with.
You do not need to put the INNER in because the default JOIN is INNER JOIN in all flavors of SQL databases. You also have 2 ORDER BY M.ID you only want the one after the WHERE.
I am not sure what you mean by more tables do you mean you tables to the JOIN or actually more tables?
I have one main table called deliveries and it has one to many relationship with deliveries_languages as dl, deliveries_markets dm and deliveries_tags dt having delivery_id as foreign key. These 3 tables have one to one relation with languages , markets and tags respectively. Additionaly, deliveries, table have one to one relation with companies and have company_is as foreign key. Following is a query that I have written:
SELECT deliveries.*, languages.display_name, markets.default_name, tags.default_name, companies.name
FROM deliveries
JOIN deliveries_languages dl ON dl.delivery_id = deliveries.id
JOIN deliveries_markets dm ON dm.delivery_id = deliveries.id
JOIN deliveries_tags dt ON dt.delivery_id = deliveries.id
JOIN languages ON languages.id = dl.language_id
JOIN markets ON markets.id = dm.market_id
JOIN tags ON tags.id = dt.tag_id
JOIN companies ON companies.id = deliveries.company_id
WHERE
deliveries.name ILIKE '%new%' AND
deliveries.created_by = '5f331347-fb58-4f63-bcf0-702f132f97c5' AND
deliveries.deleted_at IS NULL
LIMIT 10
Here I am getting redundant delivery_ids because for each delivery_id there are multiple languages, markets and tags. I want to use limit on distinct delivery_ids. So, limit 10 should not give me 10 records from above join query but 10 records where there is distinct delivery_id (deliveries.id). I probably can use derived table concept here but I am not sure how can I do that. Can someone please help me to resolve this issue.
In Postgres, you can use distinct on:
SELECT DISTINCT ON (d.id) d.*, l.display_name, m.default_name, t.default_name, c.name
FROM deliveries d JOIN
deliveries_languages dl
ON dl.delivery_id = d.id JOIN
deliveries_markets dm
ON dm.delivery_id = d.id JOIN
deliveries_tags dt
ON dt.delivery_id = d.id JOIN
languages l
ON l.id = dl.language_id JOIN
markets m
ON m.id = dm.market_id JOIN
tags
ON t.id = dt.tag_id JOIN
companies c
ON c.id = d.company_id
WHERE d.name ILIKE '%new%' AND
d.created_by = '5f331347-fb58-4f63-bcf0-702f132f97c5' AND
d.deleted_at IS NULL
ORDER BY d.id
LIMIT 10;
For larger amounts of data, this can be very inefficient. Multiple junction tables result in Cartesian products when used like this. However, for a smallish amount of data, this should solve your problem.
I am trying to select data using three tables. I need to get an equity number and contract date from an actor and contract table where the name of the film = x from a film table.
I have done:
SELECT equity_number, contract_date
FROM actor,
contract,
film
WHERE actor.equity_number = contract.equity_number
and title = 'x'
Although I am getting a column ambiguously defined error.
You don't have any Relationship with the film table.
And use a modern way of writing sql :)
SELECT a.equity_number, c.contract_date
FROM actor a
INNER JOIN contract c on a.equity_number = c.equity_number
INNER JOIN film f on f.SOMERELATIONSHIPID = c.SOMERELATIONSHIPID
WHERE f.title = 'x'
I suggest you to use JOINS instead of old comma-separated syntax. After It set aliases for each table and use these aliases in select list. Something like:
SELECT a.equity_number,
c.contract_date
FROM actor a
LEFT JOIN contract c ON a.equity_number = c.equity_number
LEFT JOIN film f ON a.film_id = f.id -- there should be related columns
AND f.title = 'x'
I have 5 different tables as shown in the pictures.
I can combine them using that query but i want to add book read log with using book names as column name into that table.
I show my tables in picture with different colors.
select dbo.Users.name+' '+dbo.Users.surname AS name_surname,
dbo.Student_Facebook_Data.likes,
dbo.Student_Facebook_Data.posts,
dbo.Student_Facebook_Data.comments,
dbo.Attendance.absence,dbo.Attendance.physical_presence,
dbo.Attendance.virtual_presence
from dbo.Users inner join dbo.Student_Facebook_Data on dbo.Users.id=dbo.Student_Facebook_Data.student_id
inner join dbo.Attendance on dbo.Users.id=dbo.Attendance.student_id
I tried that queries but these are doesn't solve my problem:
select dbo.Users.name+' '+dbo.Users.surname AS name_surname ,dbo.Student_Log.content_id
from dbo.Student_Log inner join
dbo.Users on dbo.Student_Log.student_id=dbo.Users.id
select distinct(material_name)
from dbo.Material_Detail inner join
dbo.Student_Log on dbo.Student_Log.content_id=convert(varchar,dbo.Material_Detail.id)
select distinct(material_name)
from dbo.Material_Detail inner join
dbo.Student_Log on dbo.Student_Log.content_id=convert(varchar,dbo.Material_Detail.id)
If your database is SQL Server 2005 or higher, you can definitely do it using the PIVOT operator. For clarity, I'm only showing how to display the count for books and using simplified table names:
select * from (
select u.name as 'user_name',
b.name as 'book_name',
l.id as 'reading'
from dbo.Users u
left join dbo.RealLog l on u.id = l.user_id
left join dbo.Books b on l.bid = b.id
) x
pivot (count(reading) for book_name in ([one],[two],[three],[four],[five])) as count
PIVOT Reference: http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx