sql select query among 3 tables - sql

I have three tables:
ITEMDISPLAYCOuNTS *this table stores who displayed which posts and howmanytimes
postid, count, whodisplayedid
POSTS *this table stores who posted what?
postid, whopostedid
ASPNET_USERS
userid, username
What I want at the end is who displayed whose post, and how many times, with usernames, not userids:
OUTPUT
UserNameWhoDisplayed, UserNameWhosePost, Count
I wrote the following code, but it is not functioning properly.
SELECT u1.UserName, u2.UserName, ItemDisplayCounts.Count
FROM ItemDisplayCounts AS i, Posts AS p, aspnet_Users AS u1, aspnet_Users AS u2
WHERE p.UserId = u2.UserId AND i.UserId = u1.UserId AND i.PostId = p.PostId
Can anyone suggest any corrections?

I think you want something like this (changed your joins to proper ANSI ones):
select
iu.UserName as UserNameWhoDisplayed,
pu.UserName as UserNameWhosePost,
sum(i.Count) as [Count]
from ItemDisplayCounts as i
inner join aspnet_Users as iu on iu.userid = i.whodisplayedid
inner join posts as p on p.postid = i.postid
inner join aspnet_Users as pu on pu.userid = p.whopostedid
group by
iu.UserName,
pu.UserName

If I am understanding you correctly you do not need to perform any math in the query, since you have the count field in the ITEMDISPLAYCOuNTS table. So, I do believe this will work for you:
SELECT U2.username AS UserNameWhoDisplayed,
U1.username AS UserNameWhosePost,
ID.[Count]
FROM ((POSTS AS P
INNER JOIN ASPNET_USERS AS U1 ON P.whopostedid = U1.userid)
INNER JOIN ITEMDISPLAYCOuNTS AS ID ON P.postid = ID.postid)
INNER JOIN ASPNET_USERS AS U2 ON ID.whodisplayedid = U2.userid

Related

Multiple SQL jointure

I will try to be the most intelligible possible as I'm a very beginner in SQL.
Here is my issue, I have a database with answers from questionnaries.
Each database have a user.id, unique.id, date, final score. And I would like to extract those data with a simple table which group the score of each questionnary by user.id and by date.
I have tried this :
SELECT A.user_id, SUBSTRING(A.created_at,1,10), A.SCORE, B.SCORE,
C.SCORE, D.SCORE, E.SCORE
FROM A
LEFT JOIN B
ON A.user_id = A.user_id AND SUBSTRING(A.created_at,1,10) = SUBSTRING(B.created_at,1,10)
LEFT JOIN C
ON A.user_id = C.user_id AND SUBSTRING(A.created_at,1,10) = SUBSTRING(C.created_at,1,10)
LEFT JOIN D
ON A.user_id = D.user_id AND SUBSTRING(A.created_at,1,10) = SUBSTRING(D.created_at,1,10)
LEFT JOIN E
ON A.user_id = E.user_id AND SUBSTRING(A.created_at,1,10) = SUBSTRING(E.created_at,1,10)
This is almost successful but I find out if some one did not participate to the A questionnary then I don't have anything about it.
I hope, I have been clear enough.
Thank you all,
You must manage your query with USER table (if you have it), as follow:
SELECT U.user_id, SUBSTRING(A.created_at,1,10), A.SCORE, B.SCORE,
C.SCORE, D.SCORE, E.SCORE
FROM USER U
LEFT JOIN A
ON U.user_id = A.user_id AND SUBSTRING(U.created_at,1,10) = SUBSTRING(A.created_at,1,10)
LEFT JOIN B
ON U.user_id = B.user_id AND SUBSTRING(U.created_at,1,10) = SUBSTRING(B.created_at,1,10)
LEFT JOIN C
ON U.user_id = C.user_id AND SUBSTRING(U.created_at,1,10) = SUBSTRING(C.created_at,1,10)
LEFT JOIN D
ON U.user_id = D.user_id AND SUBSTRING(U.created_at,1,10) = SUBSTRING(D.created_at,1,10)
LEFT JOIN E
ON U.user_id = E.user_id AND SUBSTRING(U.created_at,1,10) = SUBSTRING(E.created_at,1,10)
I would suggest two things, depending on how restricted you are to modify your tables.
Just use one table. Add a column testType or something like this. You can ever foreign key it and use only the keys there. That would make the recordset smaller.
Then put all your results in that one table with the matching keys.
Use UNION if the tables are all the same and have just different entries, then query this union.
There is no need for a JOIN in your case, it's better to adapt the structure.
Otherwise you can try FULL JOIN to keep all the data.

WHERE clause not functioning as expected

I am trying to join some tables to receive some data and it is not working as expected. Here is my query:
SELECT USR.PK_User AS PKUser
,USR.NAME AS NAME
FROM [User] USR
LEFT JOIN aspnet_Users ASPU ON USR.NAME = ASPU.UserName
LEFT JOIN aspnet_UsersInRoles ASPUIR ON ASPU.UserId = ASPUIR.UserId
WHERE ASPUIR.RoleId = 'E8700479-902A-42F1-A500-4FA02CAC356C'
Nothing is being returned from this query. But if I do:
SELECT * FROM [aspnet_UsersInRoles] WHERE RoleId = 'E8700479-902A-42F1-A500-4FA02CAC356C'
I get 76 selected rows. If I just do:
SELECT USR.PK_User AS PKUser
,USR.NAME AS NAME
FROM [User] USR
LEFT JOIN aspnet_Users ASPU ON USR.NAME = ASPU.UserName
LEFT JOIN aspnet_UsersInRoles ASPUIR ON ASPU.UserId = ASPUIR.UserId
I get the expected rows returned. Additionally, if I add:
WHERE ASPUIR.RoleId IS NULL
I get rows back.
What am I doing wrong?
You need the condition in the ON not the WHERE.
Otherwise you just make it back into an inner join effectively.
SELECT USR.PK_User AS PKUser,
USR.NAME AS NAME
FROM [User] USR
LEFT JOIN aspnet_Users ASPU
ON USR.NAME = ASPU.UserName
LEFT JOIN aspnet_UsersInRoles ASPUIR
ON ASPU.UserId = ASPUIR.UserId
AND ASPUIR.RoleId = 'E8700479-902A-42F1-A500-4FA02CAC356C'
Try this:-
SELECT USR.PK_User AS PKUser,
USR.NAME AS NAME
FROM [User] USR
LEFT JOIN aspnet_Users ASPU
ON USR.NAME = ASPU.UserName
LEFT JOIN aspnet_UsersInRoles ASPUIR
ON ASPU.UserId = ASPUIR.UserId
AND ASPUIR.RoleId = 'E8700479-902A-42F1-A500-4FA02CAC356C'

Proper Syntax for 3 table SELECT query

I've got 3 tables:
tblPosts
tblComments
tblUsers
I'm trying to get a listing of Posts along with associated Comments. The tricky part seems to be getting the Posts and Comments to show the proper author (User). This is the closest I get but then the Posts authors are incorrect. I'm grouping my CFOutput on "pid", so I only get each post one time as I would expect.
SELECT tblPosts.pid
, tblPosts.title
, tblPosts.description
, tblPosts.price
, tblPosts.datecreated AS pdate
, tblPosts.image1
, tblComments.comment
, tblComments.datecreated AS cdate
, tblUsers.fname
, tblUsers.lname
FROM tblPosts
LEFT JOIN tblComments ON tblPosts.pid = tblComments.pid
LEFT JOIN tblUsers ON tblComments.uid = tblUsers.uid
Any thoughts?
Thanks!
Since both tables contain an author id, you must to JOIN to tblUser twice: once for posts and once for comments. That means you must use a table alias to differentiate between the two. Something along these lines, where pa is the alias for "Post Author" and ca the alias for "Comment Author".
SELECT p.pid
, p.title
, ...
, pa.fname AS PostAuthorFirstName
, pa.lname AS PostAuthorLastName
, ca.fname AS CommentAuthorFirstName
, ca.lname AS CommentAuthorLastName
FROM tblPosts p
LEFT JOIN tblUsers pa ON pa.uid = p.uid
LEFT JOIN tblComments c ON p.pid = c.pid
LEFT JOIN tblUsers ca ON ca.uid = c.uid
I'm not familiar with all the fields in you tables. Join the post to the users table as well to get the specific users for writing posts.
How about trying this:
SELECT p.pid
,p.title
,p.description
,p.price
,p.datecreated AS pdate
,p.image1
,c.comment
,c.datecreated AS cdate
,u1.fname AS CommentAuthorsName
,u1.lname AS CommentAuthorsLastName
,u2.fname AS PostAuthorName
,u2.lname AS PostAuthorLastName
FROM tblPosts p
LEFT JOIN tblComments c
ON p.pid = c.pid
LEFT JOIN tblUsers u1
ON c.uid = u1.uid
LEFT JOIN tblUsers u2
ON p.uid = u2.uid

How to combine these two complicated queries into one query without union?

(SELECT posts.id FROM posts
INNER JOIN discussions ON discussions.post_id = posts.id
INNER JOIN companies ON discussions.company_id = companies.id
INNER JOIN subscriptions ON subscriptions.subscribable_id = companies.id AND subscriptions.subscribable_type = 'Company'
INNER JOIN users ON subscriptions.user_id = users.id WHERE users.id = 6)
UNION
(SELECT posts.id FROM posts
INNER JOIN users users_2 ON posts.analyst_id = users_2.id
INNER JOIN subscriptions ON subscriptions.subscribable_id = users_2.id AND subscriptions.subscribable_type = 'User'
INNER JOIN users ON subscriptions.user_id = users.id WHERE users.id = 6)
It should be obvious that the last join is the same in both queries.. Just not sure how to "or" together joins.
Some joins seem redundant:
discussions could be joined to subscriptions directly on the company_id column;
posts could be joined to subscriptions directly on the analyst_id column;
the last join to users in either SELECT is unnecessary as no data is retrieved from that table and the filter (users.id = 6) could be re-applied to subscriptions.user_id.
So, I would probably rewrite the query like this:
SELECT p.id
FROM posts p
INNER JOIN discussions d ON d.post_id = p.id
INNER JOIN subscription s
ON s.subscribable_type = 'Company' AND s.subscribable_id = d.company_id
OR s.subscribable_type = 'User' AND s.subscribable_id = p.analyst_id
WHERE s.user_id = 6
This is untested, but give this a try. Let me know if it works.
select posts.id
from posts
inner join discussions
on discussions.post_id = posts.id
inner join companies
on discussions.company_id = companies.id
inner join subscriptions
on subscriptions.subcribable_id = companies.id
inner join users
on subscriptions.user_id = users.id
or users.id = posts.analysis_id
where subscriptions.subscribable_type in ('Company', 'User')
and users.id = 6
I think there are differences I'm overlooking but if you just want the post if it's in the first or second without using a UNION then:
SELECT posts.id FROM posts
where posts.id IN
(
SELECT posts.id FROM posts
INNER JOIN discussions ON discussions.post_id = posts.id
INNER JOIN companies ON discussions.company_id = companies.id
INNER JOIN subscriptions ON subscriptions.subscribable_id = companies.id AND subscriptions.subscribable_type = 'Company'
INNER JOIN users ON subscriptions.user_id = users.id WHERE users.id = 6
)
or
posts.id IN
(
SELECT posts.id FROM posts
INNER JOIN users users_2 ON posts.analyst_id = users_2.id
INNER JOIN subscriptions ON subscriptions.subscribable_id = users_2.id AND subscriptions.subscribable_type = 'User'
INNER JOIN users ON subscriptions.user_id = users.id WHERE users.id = 6
)

SQL join help for friend list

I have three database tables: users, user_profiles and friends:
users
id
username
password
user_profiles
id
user_id
full_name
friends
id
usera_id
userb_id
What would be a query which finds the friends list of any user and also joins the table users and user_profiles to get the profile and user information of that friend?
Use:
SELECT f.username,
up.*
FROM USERS f
JOIN USER_PROFILES up ON up.user_id = f.id
JOIN FRIENDS fr ON fr.userb_id = f.id
JOIN USERS u ON u.id = fr.usera_id
WHERE u.username = ?
...assuming userb_id is the friend id.
This may not be the best way to do it, but this felt like the logical way:
select a.id , a.friend_id ,
Users.username
from
( SELECT id , IF(usera_id = 1, userb_id , usera_id) friend_id
FROM friends
where usera_id = 1 OR userb_id = 1 ) a
left join Users on a.friend_id = Users.id
this uses a mySQL function so probably wont work in Oracle/MSSQL
Falling back on bad habits (not using JOIN notation in the FROM clause):
SELECT a.id, a.username, a.full_name,
b.id, b.username, b.full_name
FROM friends AS f, users AS ua, users AS ub,
user_profiles AS a, user_profiles AS b
WHERE f.usera_id = ua.id
AND f.userb_id = ub.id
AND a.user_id = ua.id
AND b.user_id = ub.id
The key point is using table aliases (all those 'AS' clauses) and referencing the same table more than once when necessary.
Someone could write this with JOIN instead.
Some modification to eugene y's answer, will this work?
SELECT * FROM users u
JOIN friends f ON (f.userb_id = u.id OR f.usera_id = u.id)
JOIN user_profiles p ON u.id = p.user_id
WHERE u.id = ?