Third Table inner join - sql

I retrieve datas with inner join with two tables.This is the sql:
SELECT mc.user_id, mc.id AS movie_comment_id, mc.add_date,
mc.movie_id, mc.comment, m.id, m.name
FROM movie_comment AS mc
INNER JOIN movie AS m ON m.id = mc.movie_id
WHERE movie_id = 1500
AND stat = 'onayli'
ORDER BY mc.add_date DESC
LIMIT 10
What i want is that retriving also usernames from user table.I wrote this sql but does not work
SELECT u.id, u.username, mc.user_id, mc.id AS movie_comment_id, mc.add_date,
mc.movie_id, mc.comment, m.id, m.name
FROM movie_comment AS mc
INNER JOIN movie AS m ON m.id = mc.movie_id
ON mc.user_id = u.id
WHERE movie_id = 1500
AND stat = 'onayli'
ORDER BY mc.add_date DESC
LIMIT 10
How can i also retrieve usernames ?

You need to specify INNER JOIN at the start of each inner join.
select u.ID ,u.USERNAME,mc.USER_ID,mc.ID as Movie_Comment_ID,mc.ADD_DATE,mc.MOVIE_ID,mc.COMMENT,m.ID,m.NAME
from MOVIE_COMMENT as mc
INNER Join MOVIE as m ON m.ID=mc.MOVIE_ID
INNER JOIN [USER] u ON mc.USER_ID = u.ID
WHERE MOVIE_ID = 1500 and STAT='onayli' ORDER BY mc.ADD_DATE DESC LIMIT 10

select u.ID ,u.USERNAME,mc.USER_ID,mc.ID as Movie_Comment_ID,mc.ADD_DATE,mc.MOVIE_ID,mc.COMMENT,m.ID,m.NAME
from MOVIE_COMMENT as mc
INNER Join MOVIE as m ON m.ID=mc.MOVIE_ID
INNER JOIN usertable as u ON mc.USER_ID = u.ID
WHERE MOVIE_ID = 1500 and STAT='onayli' ORDER BY mc.ADD_DATE DESC LIMIT 10

SELECT u.ID,
u.USERNAME,
mc.USER_ID,
mc.ID as Movie_Comment_ID,
mc.ADD_DATE,
mc.MOVIE_ID,
mc.COMMENT,
m.ID,
m.NAME
FROM MOVIE_COMMENT as mc
INNER JOIN MOVIE as m ON m.ID = mc.MOVIE_ID
INNER JOIN [User] u ON u.ID = mc.USER_ID
WHERE MOVIE_ID = 1500 and STAT='onayli' ORDER BY mc.ADD_DATE DESC LIMIT 10

Related

Find all the actors that made more movies with Yash Chopra than any other director

Scehma
SELECT p1.pid,
p1.NAME,
Count(movie.mid) AS movieswithyc
FROM person AS p1 natural
JOIN m_cast natural
JOIN movie
JOIN m_director
ON (
movie.mid = m_director.mid)
JOIN person AS p2
ON (
m_director.pid = p2.pid)
WHERE p2.NAME LIKE 'Yash Chopra'
GROUP BY p1.pid
HAVING Count(movie.mid) >ALL
(
SELECT Count(movie.mid)
FROM person AS p3 natural
JOIN m_cast
INNER JOIN movie
JOIN m_director
ON (
movie.mid = m_director.mid)
JOIN person AS p4
ON (
m_director.pid = p4.pid)
where p1.pid = p3.pid
AND p4.NAME NOT LIKE 'Yash Chopra'
GROUP BY p4.pid)
ORDER BY movieswithyc DESC;
I'm not getting the right output. I'm getting zero rows . Can someone modify above query and give me the right output, I have tried various queries but not getting anything
Check this:
SELECT first.actor,
first.count
FROM (SELECT Trim(actor) AS Actor,
Count(*) AS COUNT
FROM m_cast mc
INNER JOIN (SELECT m.mid
FROM movie m) AS m
ON m.mid = Trim(mc.mid)
INNER JOIN (SELECT md.pid,
md.mid
FROM m_director md) AS md
ON md.mid = Trim(mc.mid)
INNER JOIN (SELECT p.pid,
p.NAME AS actor
FROM person p) AS pactor
ON pactor.pid = Trim(mc.pid)
INNER JOIN (SELECT p.pid,
p.NAME AS director
FROM person p) AS pdirector
ON pdirector.pid = Trim(md.pid)
WHERE director LIKE '%Yash Chopra%'
GROUP BY Trim(actor)) first
LEFT JOIN (SELECT actor,
Max(count) AS COUNT
FROM (SELECT DISTINCT Trim(actor) AS Actor,
Count(*) AS COUNT
FROM m_cast mc
INNER JOIN (SELECT m.mid
FROM movie m) AS m
ON m.mid = Trim(mc.mid)
INNER JOIN (SELECT md.pid,
md.mid
FROM m_director md) AS md
ON md.mid = Trim(mc.mid)
INNER JOIN (SELECT p.pid,
p.NAME AS actor
FROM person p) AS pactor
ON pactor.pid = Trim(mc.pid)
INNER JOIN (SELECT p.pid,
p.NAME AS director
FROM person p) AS pdirector
ON pdirector.pid = Trim(md.pid)
WHERE director NOT LIKE '%Yash Chopra%'
GROUP BY Trim(actor),
director)
GROUP BY actor) second
ON first.actor = second.actor
WHERE first.count >= second.count
OR second.actor IS NULL
ORDER BY first.count DESC
You can check the below SQL.
Explanation - First inline view returns list of people with count of their movies with 'Yash Chopra'. Second inline view returns list of people with count of their movies with other directors. At the end, I filter list of those people where count of movies with 'Yash Chopra' is greater than 'other directors'.
(select pc.name, count(distinct m.mid) count_movie
from movie m
join m_cast mc on m.mid = mc.mid
join m_director md on m.mid = md.mid
join person pc on mc.pid = pc.pid
join person pd on md.pid = pd.pid
where pd.name = 'YASH CHOPRA'
group by pc.name) lst_yc
join
(select pc.name, count(m.mid) count_movie
from movie m
join m_cast mc on m.mid = mc.mid
join m_director md on m.mid = md.mid
join person pc on mc.pid = pc.pid
join person pd on md.pid = pd.pid
where pd.name != 'YASH CHOPRA'
group by pc.name) lst_wo
on lst_yc.name = lst_wo.name
where lst_yc.count_movie > lst_wo.count_movie
SELECT *
FROM (
SELECT pc.NAME,
Count(DISTINCT Trim(m.mid)) count_movie
FROM movie m
JOIN m_cast mc
ON Trim(m.mid) = Trim(mc.mid)
JOIN m_director md
ON Trim(m.mid) = Trim(md.mid)
JOIN person pc
ON Trim(mc.pid) = Trim(pc.pid)
JOIN person pd
ON trim(md.pid )= Trim(pd.pid) where pd.NAME = 'Yash Chopra' GROUP BY pc.NAME) lst_yc
JOIN
(
SELECT pc.NAME,
count(trim(m.mid)) count_movie
FROM movie m
JOIN m_cast mc
ON trim(m.mid) = trim(mc.mid )
JOIN m_director md
ON trim(m.mid) = (md.mid)
JOIN person pc
ON trim(mc.pid) = trim(pc.pid)
JOIN person pd
ON trim(md.pid) = trim(pd.pid)
WHERE pd.NAME != 'Yash Chopra'
GROUP BY pc.NAME) lst_wo
ON lst_yc.NAME = lst_wo.NAME
WHERE lst_yc.count_movie > lst_wo.count_movie
This seems to be the answer as given by Mr. Shantanu.
But Do you know why this is taking time, I ran query 1 hour ago and no reult has produced yet.
p2.NAME LIKE 'Yash Chopra' and p1.PID
This is your line from the code.
You should have written it like this TRIM(p2.NAME),TRIM(p1.PID) because the Name and PID from your Movie Table contains spaces and things like that.You should process it correctly else it will return zero rows, keep that thing in mind.
select t.actor,t.count from ( SELECT actor,count(distinct m.mid) as count
FROM m_cast mc
INNER JOIN (SELECT m.mid
FROM movie m) AS m
ON m.mid = Trim(mc.mid)
INNER JOIN (SELECT md.pid,
md.mid
FROM m_director md) AS md
ON md.mid = Trim(mc.mid)
INNER JOIN (SELECT p.pid,
p.NAME AS actor
FROM person p) AS pactor
ON pactor.pid = Trim(mc.pid)
INNER JOIN (SELECT p.pid,
p.NAME AS director
FROM person p) AS pdirector
ON pdirector.pid = Trim(md.pid)
WHERE director LIKE '%Yash Chopra%'
--and actor like '%Uttam Sodi%'
group by actor) as t
join( SELECT actor,count(distinct m.mid) as count
FROM m_cast mc
INNER JOIN (SELECT m.mid
FROM movie m) AS m
ON m.mid = Trim(mc.mid)
INNER JOIN (SELECT md.pid,
md.mid
FROM m_director md) AS md
ON md.mid = Trim(mc.mid)
INNER JOIN (SELECT p.pid,
p.NAME AS actor
FROM person p) AS pactor
ON pactor.pid = Trim(mc.pid)
INNER JOIN (SELECT p.pid,
p.NAME AS director
FROM person p) AS pdirector
ON pdirector.pid = Trim(md.pid)
WHERE director not LIKE '%Yash Chopra%'
group by actor) as w
where t.actor=w.actor and t.count>=w.count
Hey folks who are new to sql and trying very hard to solve this question like me, you can find the part of a solution(99%) below, as i don't want to interupt your process of learning. But before going through it, try for one last time. I am thankful to the people who have discussed their various thoughts on this question in this forum, as they have triggered various ideas in me.
Before going through the solution you can have a look at this video to get an overview on various new keywords used in the below code.
disclaimer - use trim option wherever required
select actor,movies from
( select mc.pid as actor,
md.pid as director,
p.pid,
count(*) as movies,
rank() over (partition by mc.pid order by count(*) desc) as rn,
p.name
from m_director as md
join
m_cast as mc on md.mid=mc.mid
left join
person as p on md.pid=p.pid and name = 'Yash Chopra'
group by mc.pid,md.pid
)
where rn =1 and director like "nm0007181" ;
exact solution - in order to get the exact solution you can join the above table with people table to get the names of actors who had been directed more by yash chopra than any other director.
paila saisravan - data digger
select p.name,h.count
from(select mc.pid as mcpid,md.pid as mdpid,count(mc.MID) as count
from m_cast as mc
join m_director md
on md.MID=mc.MID
group by mc.pid ,md.pid
) h
join person p
on h.mcpid=p.pid
where h.count = (select count(*) as count
from m_cast as mc
join m_director md
on md.mid=mc.mid
where mc.pid=h.mcpid
group by mc.pid,md.pid
order by count(*) desc
limit 1)
and h.mdpid = (select pid
from person
where name like '%Yash Chopra%'
)
order by h.count desc

SELECT * and SELECT COUNT(*) in one query

My SQL query looks like this
SELECT *
FROM categories AS c
LEFT JOIN LATERAL (SELECT i.*
FROM influencer_profiles AS i
WHERE c.id = i.category_id
ORDER BY i.updated_at
LIMIT 2) AS i ON 1 = 1
INNER JOIN users AS u ON i.user_id = u.id
But I also want to count each influencer_profile for category to display how many influencer_profiles in each categories. How can I use COUNT(*) with selecting all columns?
SELECT *
FROM categories AS c
LEFT JOIN LATERAL (SELECT COUNT(*)
FROM influencer_profiles AS i
WHERE c.id = i.category_id
ORDER BY i.updated_at
LIMIT 2) AS i ON 1 = 1
INNER JOIN users AS u ON i.user_id = u.id
This code doesn't work.
Perhaps you just want a window function. I note that you are using left join in one place and the inner join is undoing it.
So, I am thinking:
SELECT c.*, i.*, u.*,
COUNT(*) OVER (PARTITION BY c.id) as category_cnt
FROM categories c LEFT JOIN LATERAL
(SELECT i.*
FROM influencer_profiles AS i
WHERE c.id = i.category_id
ORDER BY i.updated_at
LIMIT 2
) i
ON 1=1 LEFT JOIN
users u
ON i.user_id = u.id;

SQL Get Only Most Recent Record for A User [duplicate]

This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 4 years ago.
I have a situation where I need to write a sql query to get all of the most recent responses for a student in a classroom. I basically want to show just their most recent response, not all of their responses. I have the query to get all of the responses and order them, however I can't figure out the part where it only grabs that user's most recent record.
Below is the query I have to this point. You can see from the sample data in the image it is pulling back all responses. What I basically want is either just the most recent for a particular student OR possibly just showing the max attempt for a particular Lesson/Page number combo. I have tried playing around with partition and group bys but I haven't found the right combination yet.
SELECT U.UserName, C.Name AS 'ClassroomName', U.FirstName, U.LastName, L.Name AS 'LessonName', P.PageNumber, R.Attempt, R.Created
FROM Responses R
INNER JOIN ClassroomUsers CU ON CU.UserId = R.UserId
INNER JOIN Classrooms C ON C.Id = CU.ClassroomId
INNER JOIN Questions Q ON Q.Id = R.QuestionId
INNER JOIN Pages P ON P.Id = Q.PageId
INNER JOIN Lessons L ON L.Id = P.LessonId
INNER JOIN AspNetUsers U ON U.Id = CU.UserId
WHERE CU.ClassroomId IN (
SELECT CU.ClassroomId
FROM ClassroomUsers CU
WHERE CU.UserId = #UserId
)
ORDER BY R.Created DESC
My favorite way of doing this is using Row_Number() which will number each row based upon the criteria you set - In your case, you'd partition by U.UserName since you want one row returned for each user and order by R.Created DESC to get the latest one.
That being the case, you'd only want to get back the rows that have RN=1, so you query that out as follows:
WITH cte AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY U.UserName ORDER BY R.Created DESC) AS RN
,U.UserName, C.Name AS 'ClassroomName', U.FirstName, U.LastName, L.Name AS 'LessonName', P.PageNumber, R.Attempt, R.Created
FROM Responses R
INNER JOIN ClassroomUsers CU ON CU.UserId = R.UserId
INNER JOIN Classrooms C ON C.Id = CU.ClassroomId
INNER JOIN Questions Q ON Q.Id = R.QuestionId
INNER JOIN Pages P ON P.Id = Q.PageId
INNER JOIN Lessons L ON L.Id = P.LessonId
INNER JOIN AspNetUsers U ON U.Id = CU.UserId
WHERE CU.ClassroomId IN (
SELECT CU.ClassroomId
FROM ClassroomUsers CU
WHERE CU.UserId = #UserId
)
)
SELECT * FROM cte WHERE RN = 1
Hope that makes sense / helps!!
Just another option is using the WITH TIES clause.
Example
SELECT top 1 with ties
U.UserName
, C.Name AS 'ClassroomName'
, U.FirstName
, U.LastName
, L.Name AS 'LessonName'
, P.PageNumber
, R.Attempt
, R.Created
FROM Responses R
INNER JOIN ClassroomUsers CU ON CU.UserId = R.UserId
INNER JOIN Classrooms C ON C.Id = CU.ClassroomId
INNER JOIN Questions Q ON Q.Id = R.QuestionId
INNER JOIN Pages P ON P.Id = Q.PageId
INNER JOIN Lessons L ON L.Id = P.LessonId
INNER JOIN AspNetUsers U ON U.Id = CU.UserId
WHERE CU.ClassroomId IN (
SELECT CU.ClassroomId
FROM ClassroomUsers CU
WHERE CU.UserId = #UserId
)
Order By ROW_NUMBER() OVER(PARTITION BY U.UserName ORDER BY R.Created DESC)

how to get the counter column based on another column?

I have a table with the info about buildings, a table about expenses, a table about users and a table that does the billing.
In the billing table, I need to have a counter that counts different users inside a building.
I tried to do this with the ROW_NUMBER() but I can't get the desired result.
This is my query so far:
SELECT r.id, r.building_id AS zID,z.name AS zName,
r.user_id AS kID, k.Name AS kName,
expence_id AS uID,u.name AS uName,u.price AS uPrice,
IIF(u.unique=1,u.price,k.kvadratura * u.price) AS Balance,
r.year,r.month,
ROW_NUMBER() OVER(Partition by r.user_id ORDER BY r.id) AS Counter
FROM Bill r
INNER JOIN Expences u ON r.usluga_id = u.id
INNER JOIN Building z ON r.zgrada_id = z.id
INNER JOIN User k ON r.korisnik_id = k.id
WHERE r.building_id =7
This is my output:
What I would want to get is this:
For every user inside a building, counter+1.
You should use DENSE_RANK instead of ROW_NUMBER.
SELECT
r.id, r.building_id AS zID,z.name AS zName,
r.user_id AS kID, k.Name AS kName,
expence_id AS uID,u.name AS uName,u.price AS uPrice,
IIF(u.unique=1,u.price,k.kvadratura * u.price) AS Balance,
r.year,r.month,
DENSE_RANK() OVER(Partition by r.building_id ORDER BY r.user_id) AS Counter
FROM
Bill r
INNER JOIN Expences u ON r.usluga_id = u.id
INNER JOIN Building z ON r.zgrada_id = z.id
INNER JOIN User k ON r.korisnik_id = k.id
WHERE r.building_id = 7
Try to add expence_id to partition.
SELECT r.id, r.building_id AS zID,z.name AS zName,
r.user_id AS kID, k.Name AS kName,
expence_id AS uID,u.name AS uName,u.price AS uPrice,
IIF(u.unique=1,u.price,k.kvadratura * u.price) AS Balance,
r.year,r.month,
ROW_NUMBER() OVER(Partition by r.user_id, expence_id ORDER BY r.id) AS Counter
FROM Bill r
INNER JOIN Expences u ON r.usluga_id = u.id
INNER JOIN Building z ON r.zgrada_id = z.id
INNER JOIN User k ON r.korisnik_id = k.id
WHERE r.building_id =7

Get results from multiple tables based on relationship table

I have dbo.Users tables
Id, Name
1, John
2, Mary
3, Michael
Then I have dbo.Phones table
Id, Phonenumber
10, 1234
11, 5555
Then I have dbo.Relationship table
Id, ChildId
1, 10
2, 11
How could I make a query that returns
Id, Name, Phonenumber
1, John, 1234
2, Mary, 5555
3, Michael, NULL
This is what I got so far.
SELECT u.Id, u.Name, p.Phonenumber
FROM dbo.Users as u
LEFT JOIN dbo.Phones as p
-- Something
SQL Fiddle
Think of the Relationship table as the middle-man between your Users and Phones tables here. It is a many-to-many relationship with a mapping table. Join your Users to the Relationship and then the Relationship to your Phones.
SELECT u.Id
,u.Name
,p.PhoneNumber
FROM dbo.Users u
LEFT JOIN dbo.Relationship r ON r.Id = u.Id
LEFT JOIN dbo.Phones p ON p.Id = r.ChildId
Think of it like:
Users: Hello Relationship, I have UserId = 1, what PhoneIds do I have for that UserId?
Relationship: Hi Users. I have PhoneId = 10 for you. I'll go talk to Phones to see what the number is.
Phones: Hi Relationships! I have PhoneNumber 1234 for you. It matches the PhoneId you gave me.
Join them on id field.I would use inner join depending on the requirement
SELECT distinct u.Id, u.Name, p.Phonenumber
FROM dbo.Users as u
LEFT JOIN dbo.Phones as p on u.id = p.id
or---
SELECT distinct u.Id, u.Name, p.Phonenumber
FROM dbo.Users as u
inner join T JOIN dbo.Phones as p on u.id = p.id
inner join dbo.relationship r on r.id = u.id
where----
try this :
Select u.Id, u.Name, p.Phonenumber
From
Users u
Left join Relationship r on r.Id = u.Id
Left join Phones p on r.ChildId = p.Phonenumber