I'm triying to get ALL posts and a variable "liked" next to the post to check if the user liked it or not.
I have three table with theses :
-posts
+----+---------+---------+
| id | user_id | text |
+----+---------+---------+
-votes
+----+-----------+---------+---------+
| id | type_vote | user_id | post_id |
+----+-----------+---------+---------+
-users
+---------+---------+
| id_user | etc.. |
+---------+---------+
I check the others answers but it don't solve my problem. Also I tried this code :
SELECT id, text,
IF('$uid' IN (SELECT id FROM votes WHERE user_id='$uid'), 1, 0) AS liked
FROM posts
INNER JOIN users
ON users.id_user = posts.user_id
WHERE posts.user_id = '$uid' OR posts.user_id
ORDER BY posts.created_at desc
But it returns only posts created by user and the liked variable doesn't work..
What am I missing?
Thanks in advance !
EDIT :
I managed to get the id of the votes next to the appropriate post, how to transform it in 0 if NULL and 1 if id exists ?
SELECT p.*,(SELECT id from votes where user_id = '$uid' AND post_id = p.id) as liked from posts p
I get a result like :
+----+------+---------+---------------+
| id | text | user_id |liked |
+----+------+---------+-----+---------+
| 1 | blab | 5476zef |NULL OR post_id|
+----+------+---------+---------------+
I am not sure about the relationship between "likes" and "votes". However, if you want all posts and additional information, then a left join or correlated subquery comes to mind.
I think this may be what you want:
select p.*
(exists (select 1
from votes v
where v.post_id = p.id and v.user_id = $uid
)
) as user_flag
from p;
There may also be some condition on type_vote, but your question doesn't explain how that field is used.
SELECT products.title,isfav.isFavourite
FROM
products
LEFT JOIN isfav
ON products.product_id = isfav.product_id
and isfav.user_id=2
ORDER BY
products.added_date
You can also use an if-condition:
IF(liked IS NULL,0,1)
You can either add a column or replace liked with your expression.
Related
I want to make a SQL to get the user which name is Mark and are the author of the posts with ids 1 and 3.
NOTE: It is unknown how many posts I need to check for. So it might need to generate that part of the SQL query using PHP.
How can that be done?
Users Table:
+----+----------+
| id | name |
+----+----------+
| 1 | Mark |
| 2 | John Doe |
+----+----------+
Posts Table
+----+-------------+-------------+
| id | text | author_id |
+----+-------------+-------------+
| 1 | First Post | 1 |
| 2 | Second Post | 2 |
| 3 | Last Post | 1 |
+----+-------------+-------------+
This is just a sample case of use, not real data.
NOTE: I know how to check if user is author on one post, but not multiple in the same row. So basicly that is what I need help with, I guess it must be a left join.
For making the check for the user named Mark and check if he is author for post id 1 I do the following:
SELECT users.*
FROM users
INNER JOIN posts
ON users.id = posts.author_id
WHERE
users.name = 'Mark'
&&
posts.author_id` = 1
I just selected the id from users. If you need more columns then just add it to the select and the group by clause.
SELECT users.id
FROM users
INNER JOIN posts ON users.id = posts.author_id
WHERE users.name = 'Mark'
AND posts.author_id in (1,3)
GROUP BY users.id
HAVING count(distinct posts.author_id) = 2
Use a sub-query to find only users with both 1 and 3:
SELECT users.*
FROM users
WHERE users.name = 'Mark'
and 2 = (select count(distinct posts.id)
where users.id = posts.author_id
and posts.id IN (1,3))
SELECT users.name, posts.posts, posts.authorid
FROM users INNER JOIN posts ON users.id = posts.authorid where posts.authorid = 1
You need to use HAVING clause to achieve desired outcome:
SELECT users.name
FROM users
INNER JOIN posts
on users.id = posts.author_id
WHERE users.name = 'Mark'
GROUP BY users.name
HAVING COUNT(posts.author_id) > 1
I have been searching now for a while, but still did not find an optimal solution. I have three tables: posts, membership and comments. I want to have a Comment and reply system.
These are my tables:
Main posts:
post_id | image_url | image_thumb_url | title | text | date | sender_id
Membership:
user_id | username | pw | email |
Comments (replies) to posts:
com_id | comment | post_id_fk | user_id_fk | ip | date
I currently have a query for retrieving the posts with the membership data:
SELECT * FROM `posts`
LEFT JOIN `membership` ON `posts`.`sender_id` = `membership`.`user_id`
UNION SELECT * FROM `posts`
RIGHT JOIN `membership` ON `posts`.`sender_id` = `membership`.`user_id`
ORDER BY `post_id` DESC LIMIT $limit $start;
I now want to add the replies to each posts, containing the membership data. Does anyone have suggestion or perhaps a better solution ?
SELECT * FROM posts AS P
LEFT JOIN comments AS C
ON P.post_id = C.post_id_fk
LEFT JOIN membership AS POST_MEMBER
ON POST_MEMBER.user_id = P.sender_id
LEFT JOIN membership AS REPLY_MEMBER
ON REPLY_MEMBER.user_id = C.user_id_fk
What I would like to do is retrieve all data from a table, and order them by the number of games the user played in a specific category. Is there any way I can use some sort of "COUNT WHERE" sql statement?
here's what i have so far. it will only return the user if they have played a game in the "fps" category, but I want it to show all users in descending order even if they have not played an fps game. please excuse my crappy tables
SELECT user_data.user, COUNT(played_games.game_cat) as 'count'
FROM user_data, played_games
WHERE user_data.user_id = played_games.user_id and played_games.game_cat = 'fps'
GROUP BY user_data.user_id
ORDER BY 'count' DESC;
user_data table
user_id | user
1 | jeff
2 | herb
3 | dug
played_games table
id | user_id | game | game_cat
1 | 2 | kill | fps
2 | 1 | shoot| fps
3 | 2 | COD | fps
4 | 3 | dogs | cas
You need a LEFT OUTER JOIN to get the records even if a corresponding record does not exist in the other table.
SELECT user, coalesce(count(game_cat), 0) as count
FROM user_data LEFT OUTER JOIN played_games
ON user_data.user_id = played_games.user_id AND played_games.game_cat='fps'
GROUP BY user_data.user_id
ORDER BY count desc;
Gives the following result on my screen
+------+-------+
| user | count |
+------+-------+
| herb | 2 |
| jeff | 1 |
| dug | 0 |
+------+-------+
This is how I'd do it. No subquery, no COALESCE, no COUNTIF junk.
SELECT `users`.`user`, COUNT(`played_games`.id) AS `c`
FROM `users`
LEFT OUTER JOIN `played_games` ON
`users`.`user_id` = `played_games`.`user_id`
AND `played_games`.`game_cat` = "fps"
GROUP BY `users`.`user_id`
ORDER BY `c` DESC, `user` ASC
SQLFiddle (not sure if you can link them like this...)
Try this:
SELECT ud.user, coalesce(sum(pg.game_cat = 'fps'), 0) Total
FROM user_data ud
LEFT JOIN played_games pg ON ud.user_id = pg.user_id
GROUP BY ud.user_id
ORDER BY Total DESC
This will show all users and the amount of times they've played a game with category 'fps'.
The coalesce one is promising, but doesn't work for me, sigh~ I just found NULLIF is a good way to solve this problem. Remember to use LEFT JOIN
COUNT( NULLIF(TABLE.ATTR, 1) ) AS total_count
The TABLE.ATTR is some field that can be NULL, here is an example:
SELECT Posts.*, COUNT( NULLIF(Comments.user_email, 1) ) as comment_num
FROM (`Posts`)
LEFT OUTER JOIN `Comments` ON `Comments`.`post_id` = `Posts`.`id`
GROUP BY `Posts`.`id`
LIMIT 5
Got the idea from http://www.bennadel.com/blog/579-SQL-COUNT-NULLIF-Is-Totally-Awesome.htm
Below query the all game category with user id and order by count
select * from (SELECT user_data.user, COUNT(played_games.game_cat) as 'count'
FROM user_data, played_games
WHERE user_data.user_id = played_games.user_id(+) GROUP BY user_data.user_id)
order by count desc
Supposed I have a table posts like below:
| id | type | ref_id |
-----------+--------------+ ---------------
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 3 | 3 |
| 4 | 1 | 4 |
| 5 | 2 | 5 |
| 6 | 3 | 6 |
The type field is to join with other tables, so for example 1=blogs, 2=reviews, 3=photos, and each of them have respective fields, while ref_id is the ID of the blog/review/photo.
What i want to do is to show all latest posts (order by id DESC), while joining with all other tables based on the value of the type, but I want to do it with one query if possible. My no-good query is below:
SELECT * FROM posts
LEFT JOIN blogs ON posts.ref_id = blogs.ID AND posts.type = 1
LEFT JOIN reviews ON posts.ref_id = reviews.ID AND posts.type = 2
LEFT JOIN photos ON posts.ref_id = photos.ID AND posts.type = 3
ORDER BY posts.id DESC
The query doesn't result in anything. Another alternative is to loop the SELECT * FROM posts query and do another query based on the type, but if possible, I'd like to do it in 1 go.
Thanks for the help.
To see why your query does not return anything, consider moving the " AND posts.type = " from JOIN to WHERE clause. It will be:
select * from posts ... where type=1 and type=2 and type=3
Obviously, it will return no results. I know it is not the answer to your question, but I would consider a small change in your table definitions:
(table name: fields)
posts: id
blogs: id, post_id
reviews: id, post_id
photos: id, post_id
In this case you will be able to construct simpler and more traditional queries:
select * from posts
left join blogs on blogs.post_id = posts.id
left join reviews on reviews.post_id = posts.id
left join photos on photos.post_id = posts.id
I guess you want something like this:
( SELECT posts.*, blogs.*
FROM posts
JOIN blogs
ON posts.ref_id = blogs.ID
AND posts.type = 1
UNION ALL
SELECT posts.*, reviews.*
FROM posts
JOIN reviews
ON posts.ref_id = reviews.ID
AND posts.type = 2
UNION ALL
SELECT posts.*, photos.*
FROM posts
JOIN photos
ON posts.ref_id = photos.ID
AND posts.type = 3
)
ORDER BY posts.id DESC
I am trying to query 6 separate tables in my mysql database, the structures are as follows;
item
itemitemid | item | description | brand | date | time | path |
actor
actoractorid | name | actorthumb | bio |
brand
brandbrandid | brandname | description | image |
movie
moviemovieid | title | genre | year | moviethumb | synopsis|
users
userid | name | surname | email | password |
request
requestid | userid | itemid | brandid | movieid | actorid | content | requestdate |
Using the following query I can display for example where the requestid=1 I can see the movie in the request, the actor in the movie, the item of clothing they were wearing and its brand.
$requestid = mysql_real_escape_string($_GET['requestid']);
$query = "select r.requestid, m.*, a.*, i.*, b.*
FROM request r INNER JOIN movie m ON m.movieid = r.movieid
INNER JOIN actor a ON a.actorid = r.actorid
INNER JOIN item i ON i.itemid = r.itemid
INNER JOIN brand b ON b.brandid = r.brandid
WHERE r.requestid = $requestid";
However when I try to echo out "content" and "request date" from the request table. The data simply doesn't appear. I also cannot get the info from the user table, e.g the user logging the request by by adding the following join;
$query = "select r.requestid, m., a., i., b., u.*
INNER JOIN users u ON u.userid = r.userid
Please advise?
You aren't SELECTing those fields. Right now, you're only SELECTing r.requestid from the requests table. You need to add references to every field you want to echo.
As far as the User join, you just seem to be joining on the wrong field. You need to join on u.userid = r.userid. Right now, you're joining on u.itemid which doesn't exist. You'll also need to change your SELECT statement to report the fields you want (e.g. SELECT ... , u.name, u.email).
As an aside, you should avoid SELECTing table.* where possible. This can break things when you add a field to a table but don't account for that when processing the results of a query. You should try to be explicit as possible, and SELECT only the fields you want to use - e.g. SELECT users.name, users.email rather than doing SELECT users.*.