I have three tables, user, blog and status.
here is sqlFiddle link of my example database
user is the main table where userId and other info of user is store. I want that when I search from table user, the query should also get data from other two tables with specific userId.But only one row from blog which has maximum views,if one blog has same views then which row has max bogId that should come. and sort by views desc, if there is no blog with that userId then sort by should status id.
result comes as i want but, can someone simplify this the query.
sorry for bad English.
Is this anything like what you want ?
SELECT *
FROM user u
LEFT JOIN blog b ON u.userId = b.userId
LEFT JOIN status s ON u.userId = s.userId
WHERE MATCH(u.firstName, u.lastName, u.userName) AGAINST('harry')
GROUP BY u.userId
ORDER BY b.views
Related
So i am making this webpage (for fun to practice web dev) where users can rate or comment on a movie. One page I have is where you click on the movie for full details and it lists all the ratings and comments (together if the user has commented by review and rated through a page called "reviewMovie"...which if they went this way the rating is mandatory, otherwise they can comment on this page "listMovieReviews").
The problem I am having is incorrect details when doing my queries
the discussion table stores: the discussion ID (primary key) the timestamp of the
comment, the comment, the user who made the comment, and the movie they commented
about.
the discussion table stores: the discussion ID (primary key) the timestamp of the
comment, the comment, the user who made the comment, and the movie they commented
about.
the rating table stores: the rating ID (primary key), the movie being rated, the
user who did the rating, and the rating score (out of 10)
So some examples of the combined data are:
User1 (user1) has rated "American Psycho" a 4/10 and has made a comment "comment1" on
it
User2 (admin..for testing purposes) has rated "American Psycho" a 8/10 and has made a
comment "comment2" on it
So on the page that lists the details of "American Psycho" and the ratings/comments I should have this list of ratings and comments:
<TIMESTAMP FOR COMMENT1> User1 Rating 4/10 "comment1"
<TIMESTAMP FOR COMMENT2> admin Rating 8/10 "comment2"
Using the following queries:
SELECT *
FROM discussion
INNER JOIN users ON discussion.userID = users.userID
WHERE discussion.movieID = <American Psycho's Movie ID>;
AND
SELECT *
FROM ratings
INNER JOIN movies ON ratings.movieID = movies.movieID
WHERE ratings.movieID = <American Psycho's Movie ID>;
I get this:
<TIMESTAMP FOR COMMENT2> admin Rating 4/10 "comment2"
<TIMESTAMP FOR COMMENT2> admin Rating 8/10 "comment2"
I have tried several other INNER JOINS with joining the table that stores user information and table that stores movies information but I keep getting mixed data
Also tried DISTINCT and UNION but still to no avail
Where am I going wrong??
Also first post so sorry If I have not been too clear, bad formatting, or not shown enough work but I am really really stuck
I assume:
A movie could have from 0 to n comments.
A movie could have from 0 to n ratings.
A user could rate a movie only once or none.
A user could comment a movie from 0 to n times.
Your queries are fine, maybe your problem is in your php code.
You have to account that a user maybe comment a movie several time and never rated it.
In second query you should JOIN with user (instead of with movie, because you do not get movie information) to get the user name.
Maybe you should display the info in two table: one for ratings and other for comments.
(You have to replace quotation marks by movie ID)
SELECT u.userName, r.score
FROM ratings AS r
INNER JOIN users AS u ON r.userID = u.userID
WHERE r.movieID = ?;
SELECT u.userName, d.commentTime, d.comment
FROM discussion AS d
INNER JOIN users AS u ON d.userID = u.userID
WHERE d.movieID = ?;
You could group all comments per user in one row this way (but I think this is not what you are looking for):
SELECT u.userName, GROUP_CONCAT(CONCAT(d.commentTime, ': ', d.comment) SEPARATOR '; ') AS comments
FROM discussion AS d
INNER JOIN users AS u ON d.userID = u.userID
WHERE d.movieID = ?
GROUP BY u.userName
I think do not have sense to make one query in this case, but if you want get all data in one query you could try something like this:
You will have a comment per row, so for example if a user make two comment you will have two rows for the same user with the same score.
First I get all user that comment or rating the selected movie and make a CROSS JOIN between movie and these users. Then I make a LEFT JOIN with discussion ON movieID and userID and another LEFT JOIN with ratings ON movieID and userID.
You need to make LEFT JOIN instead of INNER JOIN because if a movie do not have ratings or comments your result will be empty.
In SELECT clause you should list only the columns that you need.
SELECT *
FROM movies m
CROSS JOIN (SELECT d.userID
FROM discussion d
WHERE d.movieID = ?
UNION
SELECT r.userID
FROM ratings r
WHERE r.movieID = ?) AS u
LEFT JOIN discussion AS d ON m.movieID = d.movieID AND u.userID = d.userID
LEFT JOIN ratings AS r ON m.movieID = r.movieID AND u.userID = r.userID
LEFT JOIN users ON u.userID = users.userID
WHERE m.movieID = ?;
You need to join all three tables.
SELECT *
FROM movies AS m
JOIN ratings AS r ON r.movieID = m.movieID
JOIN discussion AS d ON d.userID = r.userID AND d.movieID = m.movieID
WHERE m.movieID = <American Psycho's Movie ID>
ORDER BY r.userID, d.timestamp
This will repeat the movie and rating information for each comment. You can remove those duplicates in the application code that displays the results. See How can i list has same id data with while loop in PHP? for an example of how to do this.
SELECT * FROM movies AS MOVIE
JOIN ratings AS RATING ON `RATING.movieID` = `MOVIE.movieID`
JOIN discussion AS DISCUS ON `DISCUS.userID` = `RATING.userID`
WHERE `MOVIE.movieID` = <SOME Movie ID>
ORDER BY `RATING.userID`, `DISCUS.timestamp`
I have two tables, one for the posts and another for the users. I am fetching all posts from the 'posts' table and user data (who posted that post) from the tbl_users.
currently, I am using this query :
$query = $pdo->prepare("SELECT * FROM `posts`,`tbl_users` WHERE id = user_id_p ORDER BY `post_id` DESC");
$query->execute();
return $query->fetchAll();
it is working fine, it is fetching all the posts from the posts table and user data from tbl_users.
However, my issue is this that I don't want to fetch all posts, but I want to fetch only those posts which are posted by the specific user(for example by John only) and the user data for John only from the tbl_user.
(field Id from tbl_users and field user_id_p from the table posts are same in both the tables.)
Any suggestions or help?
Although your query is working, it is not at all efficient because it uses an implicit cross join which results in a very large resultset.
Use a proper INNER JOIN with a condition applied with WHERE:
SELECT u.*, p.*
FROM tbl_users u INNER JOIN posts p
ON u.id = p.user_id_p
WHERE u.id = ?
ORDER BY p.post_id DESC
Replace ? with the id of the user.
You can use JOIN for this. Example
select P.name, U.name from post P NATURAL JOIN user U;
I have two tables in database, named users(store user details) and posts(store post details). Now i want to get data from both tables. Like user_image from users and post description from post.
I am using this query
SELECT * FROM `users`AS u,`posts` WHERE u.user_id IN (SELECT user_id FROM `posts`)
But it returns duplicate data. I have 2 users and 3 posts but it returns 6 posts.
Try something like:
Select a.user_image, b.post_description from users as a join posts as b on a.user_id = b.user_id
Do an inner join & you shall get the desired result
In the above query a & b are alias for the two different tables. I you do not want to use alias you can also write it as users.user_image in your select statement.
Write the fields you want from both the tables in your select statements.
The below image will help you understand the inner join
Inner Join Circle for understanding
Use group by as below:
SELECT * FROM `users`AS u,`posts` WHERE u.user_id IN (SELECT user_id FROM `posts`) group by u.user_id
What about
Select * FROM user u right join posts p on u.id = p.user_id
?
if you want to get data from both tables you need to use joins.and you make sure the two tables are interlinked by primary keys
so use this can help
select user_image,post_description from users join posts on users.user_id=posts.user_id;
I'm not too good with explaining things, apologies.
I have 3 tables that are similar to the below:
users
id
username
threads
id
title
user_id
lastpost_id
posts
id
content
thread_id
user_id
On a page listing forum threads, I want the username of both the thread author, and the last post author of that thread to be displayed, I'm attempting to achieve this in a single query.
My query looks like this:
SELECT t.*,u.username FROM threads t
INNER JOIN users u ON t.user_id=u.id
INNER JOIN posts p ON t.lastpost_id=p.id
ORDER BY t.id DESC
The first join enables me to get the username of the user id that started the thread.
The second join is what I'm not sure on, it can get me the user id but how do I get the username from that, as a 3rd join?
You can select the same table multiple times if you give it a different alias. You can give the fields aliases too:
SELECT
t.*,
tu.username as threadusername, /* Result field is called 'threadusername' */
p.*,
pu.username as lastpostusername
FROM threads t
INNER JOIN users tu ON t.user_id=tu.id /* thread user */
INNER JOIN posts p ON t.lastpost_id=p.id
INNER JOIN users pu ON p.user_id=pu.id /* post user */
ORDER BY t.id DESC
You can join to a joined table like this:
SELECT t.*,u.username,u2.username FROM threads t
INNER JOIN users u ON t.user_id=u.id
INNER JOIN posts p ON t.lastpost_id=p.id
INNER JOIN users u2 ON p.user_id=u2.id
ORDER BY t.id DESC
Note, I haven't had time to test it, but it should work (at least in MySQL).
I don't know if I got it correctly, but as per my understanding you can have a inner query to fetch the thread ids and then have a outer query to fetch the posts based on the thread id, have a max on post id and group by user id. Also join to user to have the name. Hope that helps.
i have a join query that displays info from 2 tables, but if a record is deleted from one of the tables, the joined record doesn't show. i still want to display the joined record but with the data from the first table showing and the info with the second table missing.
here is the query i'm working with.
$result = mysql_query("SELECT user_groups.*, pricing_groups.* FROM user_groups inner join pricing_groups on user_groups.pricing_group_id = pricing_groups.id LIMIT 2,18446744073709551615")
i'm limiting it by 2. i still want that in next version.
if record from pricing_groups is deleted that is attached to a record from user_groups, it's ok to show the user group info. in fact, i want it to display the user group info. but if it's the other way around...if a user group is deleted, then it's ok not to show either the user group info or pricing group info.
To include all records from user_groups you would need to use a LEFT JOIN like so:
SELECT ug.*, pg.*
FROM user_groups AS ug
LEFT JOIN pricing_groups AS pg
ON ug.pricing_group_id = pg.id
LIMIT 2,18446744073709551615
The LEFT JOIN returns all rows from the left table (user_groups), with the matching rows from the right table (pricing_groups). The result is NULL in the right side when there is no match.