Select all from table where value=multiple values from another table - php

I'm trying to select posts that are posted by somebody the user is following.
My posts table looks like this:
My followers table looks like this:
The "creator" column in the posts table is the ID of the user who posted it. The "follower" colum in the followers table is the user who is following the "following" column.
I'm using this query (to no avail) to select all from posts where creator=all users the user is following:
SELECT * FROM posts WHERE creator=(SELECT following FROM followers
WHERE follower=the user's id) ORDER BY datetime DESC;
In theory:
SELECT * FROM posts WHERE creator=1 or 2 or 3 or 4...or 998 or 999
etc, etc.
What would be the best way to do this?
Thanks!

Try changing the query to:
SELECT * FROM posts WHERE creator in (SELECT following FROM followers WHERE follower=the user's id) ORDER BY datetime DESC;

Using joins in this case can boost up the performance of your query. I recommend the following:
SELECT * FROM posts p
INNER JOIN followers f
ON p.creator = f.following
WHERE f.follower = <user_id>
ORDER BY datetime DESC;

Try it
SELECT *
FROM posts p, followers f
WHERE
p.creator=f.following
and f.follower ='user_id'
ORDER BY p.datetime DESC;

Related

SQL: How do I filter (WHERE) a joined (ON) table in SQL?

I have two tables (users and posts) and I want to write out all posts (among other things) by one user. I'm thinking I should use a JOIN and WHERE but I get an error for using WHERE.
This is my code:
SELECT username, post, joinDate, title, info FROM users
WHERE userId='18'
JOIN posts ON users.userId=posts.userId
ORDER BY date DESC
I'm new to this and perhaps there is a better way but I can't figure it out atm.
Thankful for all answers!
The JOIN clause comes before the WHERE clause, after the FROM clause. First you join together all the tables you need, then you do your filtering with WHERE. Like this:
SELECT username, post, joinDate, title, info
FROM users
JOIN posts ON users.userId=posts.userId
WHERE users.userId='18'
ORDER BY date DESC
try like below
SELECT u.*,p.*
FROM users u JOIN posts p ON u.userId=p.userId
WHERE u.userId=18
ORDER BY date DESC
where will be after join and 18 is int datatype value so not need single quote for this and use alias for avoiding ambigous column name
SELECT username, post, joinDate, title, info
FROM users
JOIN posts ON users.userId=posts.userId and users.userId='18'
ORDER BY date DESC
if userId is in users table then YES you can use where userId='18'.
If userId is in posts table then it should be userId='18' be in join part.

Mysql select oldest record for each user

I'm trying to create a list in PHP of the oldest entries for each user in the database.
SELECT *,
MIN(`entries`.`entry_date`)
AS entry_date
FROM (`entries`)
JOIN `user_profiles`
ON `user_profiles`.`user_id` = `entries`.`user_id`
WHERE `status` = 1
GROUP BY `entries`.`user_id`
I'm using the query to retrieve from the entries table the oldest dated entry using MIN()and joining with table user_profiles for other data. The query should select the oldest entry for each user. It seems to work but it retrieves the wrong entry_date field on some entries when I echo them. Please help, I can't spot what I'm doing wrong..
You need to use a subquery to obtain the (user_id, entry_date) pairs for each user, then join that with a query that selects the records of interest:
SELECT *
FROM entries
NATURAL JOIN (
SELECT user_id, MIN(entry_date) AS entry_date
FROM entries
GROUP BY user_id
) AS tmin
JOIN user_profiles USING (user_id)
WHERE status = 1
Have you tried approaching the problem from the user_profiles table instead of the entries table? If a user has no entries, they will not appear in the above query.
This may help, but I'm not sure if it's the full solution:
SELECT *, MIN(entries.entry_date) as entry_date
FROM user_profiles LEFT JOIN entries USING (user_id)
WHERE status = 1
GROUP BY user_profiles.user_id
Also, you're renaming the MIN(entires.entry_date) as entry_date... but you already have a column named entry_date. Try renaming the derived columns to something unique like "min_entry_date"?

Using the MySQL select statement

I would like to select the posts from users based on who the logged in user is following. What would I need to do? How do I use two different tables with one SELECT statement? I don't even know where to start.
I have 3 tables:
users
posts
followers
Thanks.
SELECT p.*
FROM followers f
JOIN posts p
ON p.author = f.following_id
WHERE f.user_id = $logged_in
ORDER BY
p.post_date DESC
I had to make up the field names as you haven't provided them.
Selecting from two tables is done using JOINs
http://dev.mysql.com/doc/refman/5.0/en/join.html
basically you select from two tables and define JOIN condition.
Assume you have two tables:
users with columns: user_id, user_name, online_state
posts with columns: post_id, user_id (user who posted this post), title, message
SELECT p.title, p.message FROM users u JOIN posts p ON u.user_id = p.user_id WHERE u.online_state = 'online'
join condition should be after ON, non-join condition after WHERE
I would go with the Join query as Quassonoi suggested in his answer, If you want to try an alternate solution, you can do it with subquery like this
SELECT P.PostId,P.Title,P.Body
FROM Post P WHERE P.CreatedById
IN (
SELECT FollowerID from Followers WHERE USER_ID=3
)
Replace 3 with the current user id. Assuming your table structure is something like this.
POST
PostId (int)
Title
Body
Followers
UserId (int)
FollowerId (int)

How can I display the article of a specific user according to the number of views of this article?

I have a table that contains articles posted by users. The structure of the table is like this:
id uid author article_name article num_views edit_time
id is the article id, uid is the author id and num_views is how many times this article is being viewed.
What I need is to display ONLY the most viewed article according to uid
In short , if uid is author id and article id is 5 , what I need is to display something like :
id uid article_name num_views
5 1 article title 100
I tried to run several queries in Mysql but i could not figure it out , can anyone help please ??
The most viewed article and its count by each user:
SELECT `id`, `uid`, `article_name`, `num_views`
FROM `table`
WHERE `num_views` IN (
SELECT MAX(`num_views`) FROM table GROUP BY `uid`)
For only given uid
SELECT `id`, `article_name`, MAX(`num_views`)
FROM `table`
WHERE `uid` = <user id>
If you need only one entry you should try to sort your query with ORDER BY command and limit it to the one article by LIMIT 1 command.
SELECT * FROM ARTICLES WHERE (some criteria) ORDER BY NUM_VIEWS DESC LIMIT 1.
That should select an article with the most views.
It's a bit hacky and if your table gets big it's going to be non-performant, but one way to do this would be:
select uid,
group_concat(id order by num_views desc) as most_viewed_id,
group_concat(article_name order by num_views desc) as most_viewed_name,
group_concat(num_views order by num_views desc) as num_views
from yourtable group by uid
You'll then have to parse out the first element from each of the group_concat'd fields.
Another way would be to use a join with a subquery, but it can be weird if there's two articles for the same user with the same highest number of views, and also has performance issues:
select uid,num_views,id,article,article_name from
yourtable join
(select uid,max(num_views) as maxviews from yourtable group by uid) as subtable
using (uid,num_views)
Of course at a certain point the best way might be to just iterate over uids with a simple order by query. It's a lot more queries but it can be faster depending on your data. Unfortunately SQL just isn't really set up to do queries like this.

Subquery selecting over a select

I have a table users structured as follow:
userUID (int), userName (varchar), userImage (varchar)
And a table 'posts' structured as follow
postPID (int), postUID (int), postMessage (char)
Now, the postUID correspond to the author UID.
When i SELECT the posts, i'd like to also select the userName and userImage field corresponding to the postUID.
How could i do that?
SELECT p.*, u.userName, u.userImage
FROM users u
JOIN posts p
ON p.postUID = u.userUID
Select
p.postPID,
p.postUID,
p.postMessage,
u.userName,
u.userImage
From posts p
Join users u
On p.postUID = u.userUID
It's better to name your columns instead of selecting * as has been discussed on here in numerous threads.
It depends on how many records are returned. If not sure it is good to have top 10 or top 100 so that it only returns that many rows.

Categories