I have this subquery where I am getting the posts of users that a user is following. This is the subquery.
$query = "SELECT * FROM `Posts` WHERE UserID IN
(
SELECT Followed FROM `Follow` WHERE Follower = ?
)
ORDER BY PostDate DESC
";
// on bind_param ? will be $userID
This works fine but I also want to get the user's own posts and then data from a profiles table so I'm probably going to ditch the subquery for some sort of join. I've used inner joins before however the profile/posts table have a common id 'UserID' but the Follow table does not. Would a full join work or would I have to use an AS ?
A union might be best.
SELECT * FROM posts WHERE UserID = ?
UNION ALL
SELECT P.*
FROM posts P
INNER JOIN follow F ON F.followed = P.UserID
WHERE F.follower = ?
Related
I have following query
select * from user_profile
Now i want to add where condition check user status from other table (users)
select * from user_profile,users where users.status!=0
Please Do Not Recommend Join i following old join query
Thanks
If you don't want to use join, you have to use a subquery. I guess both tables have a column like userId:
select * from user_profile where userId in (select userId from users where status != 0)
try this using sub query
select * from user_profile where status!=(select status from users where id =? or status=?)
what you compare id or status in subquery
Assuming you have a relation column (say user_id or perhaps profile_id or something -- not sure until you share sample data as requested.) between the two tables, you can join the two table and filter the rows like this:
select *
from user_profile p
join users u on p.user_id = u.user_id
where u.status != 0;
If you want every column from both tables in your query, you can use:
SELECT * from user_profile, users WHERE user_profile.user_id = users.id AND users.status! = 0
Where I assumed you have some column(like user_id - user_profile
and id - users in my example) that links both tables together.
I'm new at this and don't comprehend Mysql very well. I'm trying to retrieve ALL media uploaded by a certain user, and sort it all by the date it was uploaded. Problem is, the media is in 3 different tables. Can someone provide me with a good solution?
$sql1 = "SELECT * FROM videos WHERE user_id = $user_id";
$sql2 = "SELECT * FROM photos WHERE user_id = $user_id";
$sql3 = "SELECT * FROM audios WHERE user_id = $user_id";
SORT DESC BY $result['upload_date'];
You want to create a JOIN. If you only want rows where there are existing relationships, you can use an inner join, set up like this:
SELECT *
FROM videos v
JOIN photos p ON p.user_id = v.user_id
JOIN audios a ON a.useR_id = p.user_id
ORDER BY upload_date DESC;
The above will select all columns, which may have some repeated things. For example I believe user_id will show up once for each table you joined, so I would narrow down your select clause.
what is the right way to write this sql query
select * from articles where id = 1;
select * from users where id = user_id in articles table;
my question is how to write the second sql statement properly
From your question I am unable to understand what you are really looking for. I think you need to inner join two tables. The query below will give you the result by joining both the tables and it will consider USER_ID column in ARTICLES table represents ID column in USERS.
SELECT * FROM USERS INNER JOIN ARTICLES ON USERS.ID = ARTICLES.USER_ID WHERE USERS.ID = 1;
select * from users where user_id in (select id from articles);
With additional filtering inside select from articles for example. Again, depends on the requested result.
SELECT *
FROM articles
INNER JOIN users ON articles.id = users.user_id
WHERE id = '1'
Or use it as a sub query
SELECT *
FROM users
WHERE user_id IN (SELECT ID
FROM articles
WHERE id = '1')
I have a db structure like:
posts
id
title
content
users
id
....
post_reads
post_id
user_id
How can I count the number of posts for which a particular user with an id say, x does not have a read record.
My SQL query currently looks like:
SELECT COUNT(posts.id) AS c
FROM `posts`
LEFT JOIN `post_reads` ON (`posts`.`id` = `post_reads`.`post_id`)
LEFT JOIN `users` ON (post_reads.user_id = `users`.`id` AND post_reads.user_id = x)
WHERE users.id IS NULL
AND post_reads.user_id IS NULL
I know I'm doing something wrong, although I'm not sure what that is.
This should to the trick
SELECT COUNT(posts.id) AS c
FROM posts
LEFT JOIN post_reads ON posts.id = post_reads.post_id AND post_reads.user_id = x
LEFT JOIN users ON post_reads.user_id = users.id
WHERE users.id IS NULL
Note that if you're not interested in doing anything with table users you can shorten this query to:
SELECT COUNT(posts.id) AS c
FROM posts
LEFT JOIN post_reads ON posts.id = post_reads.post_id AND post_reads.user_id = x
WHERE post_reads.user_id IS NULL
The first join you were doing is really an inner join, because it will never 'misfire'.
The second join will sometimes misfire, because you have the extra condition in there.
Therefore using the post_reads.some_id is null will never be true.
In order for that to work you'd have to repeat the AND post_reads.user_id = x in that join condition as well, but putting it in twice is silly and not needed, once will do.
PS don't forget to replace the 'x' with something more useful :-)
I tried this a few ways just using JOINS/WHERE, but they tend to miss certain cases (i.e. you can exclude posts joined to a read record for the given user, but the posts' ids will still be returned if they also join to read records for other users).
The simplest way may be something like this:
SELECT COUNT(DISTINCT id)
FROM posts
WHERE id NOT IN (SELECT DISTINCT post_id FROM post_reads WHERE user_id = #x)
Also, note that I don't believe you need to surround identifiers in backticks unless they are MySQL keywords.
I have three tables (user, friends, posts) and two users (user1 and user2).
When user1 adds user2 as friend then user1 can see the posts of user2 just like on Facebook. But only the posts after the date when user1 added user2 as friend. My query is like this:
$sql = mysql_query("SELECT * FROM posts p JOIN friends f ON
p.currentuserid = f.friendid AND p.time >= f.friend_since OR
p.currentuserid='user1id' WHERE f.myid='user1id'
ORDER BY p.postid DESC LIMIT 20");
it is working all the way fine but with a little problem.....!!
it displays user2, user3 (all the users as friends of user1) posts for single time but shows user1 posts multiple.......i.e
user2. hi
user1. userssfsfsfsfsdf
user1. userssfsfsfsfsdf
user3. dddddddd
user1. sdfsdsdfsdsfsf
user1. sdfsdsdfsdsfsf
but i in database it is single entry/post why it is happening........!!
How can I fix it?
I'm not a SQL expert, but I think your problem is in the JOIN condition. I cannot see a way how you can join with posts and friends and get the result that you need. A SQL expert may know this, but for me it's just too difficult.
If I were you I would break the problem down in 2 parts:
Select the user's own posts
Select the user's friend's posts
For example, you can do this by using 2 different conditions and do the join with the friends table in a sub query (I have not tested this!):
select *
from posts p
where
p.currentuserid = 'user1id'
or
p.postid in
(
select p2.postid
from posts p2
join friend f on p2.currentuserid = f.friendid
where p2.time >= f.friend_since and f.myid='user1id'
)
Another way to do it is to use a union (also not tested..):
select *
from posts p
where
p.currentuserid = 'user1id'
union
select p2.*
from posts p2
join friend f on p2.currentuserid = f.friendid
where p2.time >= f.friend_since and f.myid='user1id'
I think, the easiest solution is to use GROUP BY statement on column posts.userId to remove duplicate entries. However it is not optimized way to solve the problem.
The reason you're getting the posts of all of user1's friends is you're not qualifying which friend's posts the query should return.
Add a f.friendid = 'user2id' (or whatever the column name is) in there before the WHERE clause.
You really should give some idea of what the schema looks like so we don't have to make so many assumptions. I'm assuming the primary key of user is id, and friends has a userid as well as a friendid field. I'm also assuming posts.currentuserid is the id of the user who created the post. If not, replace it with posts.userid or whatever the correct field is.
The reason your query doesn't work right is that you need at least 2 joins. When creating a query, it's easiest to start with what you have and work up to what you want, one join at a time. Here's the query to get the posts that a particular user can read:
SELECT p.*
FROM user u
JOIN friends f ON u.id = f.userid
JOIN posts p ON ((u.id = p.currentuserid) OR (f.friendid = p.currentuserid AND p.time >= f.friend_since))
WHERE u.id = ?
ORDER BY p.postid DESC LIMIT 20
The second join is where the meat is. It specifies that in order to read a post it (a) has to be written by you or (b) has to be written by a friend of yours AFTER you friended them.
If you want to also get the name of the user who created the post (assuming user.name holds the user name) you need a 3rd join:
SELECT pu.name as 'Posted By', p.*
FROM user u
JOIN friends f ON u.id = f.userid
JOIN posts p ON ((u.id = p.currentuserid) OR (f.friendid = p.currentuserid AND p.time >= f.friend_since))
JOIN user pu ON p.currentuserid = pu.id
WHERE u.id = ?
ORDER BY p.postid DESC LIMIT 20