Filter MySQL result w/ empty row - php

I have searched high and low to filter my mysql query but WHERE NOT NULL does not work. I hope somebody could help me. I have some columns that are empty named 'path'. And I want to filter these out.
My query:
SELECT
p.path, p.title, p.body, p.post_date, u.username FROM pages p
LEFT JOIN users u ON p.post_author = u.id
ORDER BY p.id ASC
How can I get this done? Thanks.

SELECT
p.path, p.title, p.body, p.post_date, u.username
FROM pages p
LEFT JOIN users u ON p.post_author = u.id
WHERE
p.path IS NOT NULL AND
p.path <> ''
ORDER BY p.id ASC
So does this help or you are asking something different?

try with php to check the empty field:
$query = "SELECT
p.path, p.title, p.body, p.post_date, u.username FROM pages p
LEFT JOIN users u ON p.post_author = u.id
ORDER BY p.id ASC";
$result = mysql_query($query);
while( $row = mysql_fetch_assoc($result) ){
// Check for empty record
if( !empty($row['path']) ){
echo $row['path'];
}
}

Try this one, this might work.
SELECT
p.path, p.title, p.body, p.post_date, u.username FROM pages p
LEFT JOIN users u ON p.post_author = u.id
WHERE p.path IS NOT NULL AND p.path <> ''
ORDER BY p.id ASC

Related

Add a WHERE clause to a MySQL query

I have this MySQL query that works really well. What it's doing is displaying all the filenames (filename) in a database, along with the poster of that filename and then any user who is tagged with that filename (cp.user_id). Later on in the script I explode the tagGroup.
I have a created a new field in the tbl_collab table called 'approved' which can either be 'yes' or 'no' and I want to know how to add a WHERE clause to my query so only the users where approved="yes" in tbl_collab are displayed. How can I do this? Many thanks.
"SELECT up.id, up.file, up.title, p.user_name, p.user_id, GROUP_CONCAT(CONCAT(cp.user_id, '~', cp.user_name) SEPARATOR '|') AS tagGroup
FROM tbl_uploads up
LEFT JOIN tbl_users p ON up.user_id = p.user_id
LEFT JOIN tbl_collab c ON up.file = c.file
LEFT JOIN tbl_users cp ON cp.user_id = c.collab_userid
GROUP BY up.file ORDER BY up.id DESC LIMIT ? , ?"
This is how I am exploding the tagGroup.
$tag_array = explode('|' , $tagGroup);
foreach($tag_array as $tag) {
list($uid,$uname) = explode('~',$tag,2);
You can add this condition in where clause like
"SELECT up.id, up.file, up.title, p.user_name, p.user_id, GROUP_CONCAT(CONCAT(cp.user_id, '~', cp.user_name) SEPARATOR '|') AS tagGroup
FROM tbl_uploads up
LEFT JOIN tbl_users p ON up.user_id = p.user_id
LEFT JOIN tbl_collab c ON up.file = c.file
LEFT JOIN tbl_users cp ON cp.user_id = c.collab_userid
WHERE c.approved = 'yes'
GROUP BY up.file ORDER BY up.id DESC LIMIT ? , ?"
Or you can add this condition in joining condition like
"SELECT up.id, up.file, up.title, p.user_name, p.user_id, GROUP_CONCAT(CONCAT(cp.user_id, '~', cp.user_name) SEPARATOR '|') AS tagGroup
FROM tbl_uploads up
LEFT JOIN tbl_users p ON up.user_id = p.user_id
LEFT JOIN tbl_collab c ON up.file = c.file AND c.approved = 'yes'
LEFT JOIN tbl_users cp ON cp.user_id = c.collab_userid
GROUP BY up.file ORDER BY up.id DESC LIMIT ? , ?"
Add WHERE c.approved = 'yes'to your sql query ;) or change the JOIN-condition to LEFT JOIN tbl_collab c ON (up.file = c.file AND c.approved = 'yes')

LIMIT results on specific table when using LEFT JOIN

Below is my query. I would like to get only 10 posts from post table. However it LIMIT 10 below doesn't limit the results in posts table but it does on another table.
Can anyone help me to fix the query? I really appreicate your help.
SELECT posts.id , posts.cat_id , posts.school_id , posts.campus_id , posts.status , posts.priority , posts.title , posts.content , posts.phone , posts.email , posts.tags , posts.zip , posts.price_new , posts.price_old , posts.reviewed_by , posts.reviewed_date , posts.updated_date , posts.posted_date , posts.expired_date , posts.ip_address , schools.school_name, campuses.campus_name , meta.meta_key , meta_value , images.img_name
FROM posts LEFT JOIN
meta
ON posts.id = meta.post_id LEFT JOIN
images
ON posts.id = images.post_id LEFT JOIN
schools
ON posts.school_id = schools.id LEFT JOIN
campuses
ON posts.campus_id = campuses.id
ORDER BY posts.updated_date DESC LIMIT 10
One method is to use a subquery:
SELECT p.id , p.cat_id, p.school_id, p.campus_id , p.status,
p.priority, p.title, p.content, p.phone, p.email, p.tags, p.zip,
p.price_new, p.price_old, p.reviewed_by, p.reviewed_date,
p.updated_date, p.posted_date, p.expired_date, p.ip_address,
s.school_name, c.campus_name,
m.meta_key, m.meta_value,
i.img_name
FROM (SELECT p.*
FROM posts p
ORDER BY p.updated_date DESC
LIMIT 10
) p LEFT JOIN
meta m
ON p.id = m.post_id LEFT JOIN
images i
ON p.id = i.post_id LEFT JOIN
schools s
ON p.school_id = s.id LEFT JOIN
campuses c
ON p.campus_id = c.id;
Note that the use of table aliases makes the query easier to write, read, and understand.

MYSQL Query - Get current user's posts and the user's he's following posts

I am trying to query to get the current user's posts and the posts of the people he is following. Like most social networks do in their home page.
I know how to query all of the current user's posts, but I am struggling to get the user's he's following posts.
I saw this other question Mysql select query for getting current user post and followed friend post
But the answer there isn't really helping me...
Here's is my query so far:
SELECT P.id,
P.caption,
P.date,
U.id,
U.fullname,
U.username,
F.IdOtherUser
FROM USERS AS U
INNER JOIN Activity AS F
ON U.id = F.id
INNER JOIN Posts AS P
ON P.id = U.id OR P.id = F.IdOtherUser
WHERE P.id = 145
ORDER BY P.id DESC
145 = current user.
Activity.IdOtherUser = the user '145' is following
Activity.id = will be '145' the current user
If anyone can help me sort this I'd appreciate it alot!
Cannot seem to understand it fully, as I am quite new to MYSQL...
Fix
(SELECT P.id as postid,
P.caption,
P.date,
U.id as userid,
U.fullname,
U.username,
coalesce(Activity.LikeCNT,0),
Activity.CurrentUserLiked
FROM USERS AS U
INNER JOIN Posts AS P
ON P.id = U.id
LEFT JOIN (SELECT COUNT(DISTINCT Activity.uuidPost) LikeCNT, Activity.uuidPost, Activity.id, sum(CASE WHEN Activity.id = 145 then 1 else 0 end) as CurrentUserLiked
FROM Activity Activity
WHERE type = 'like'
GROUP BY Activity.uuidPost) Activity
ON Activity.uuidPost = P.uuid
AND Activity.id = U.id
WHERE U.id = 145)
UNION
(SELECT P.id,
P.caption,
P.date,
U.id,
U.fullname,
U.username,
coalesce(Activity.LikeCNT,0),
Activity.CurrentUserLiked
FROM Activity AS A
INNER JOIN USERS AS U
ON A.IdOtherUser=U.id
INNER JOIN Posts AS P
ON P.id = U.id
LEFT JOIN (SELECT COUNT(DISTINCT Activity.uuidPost) LikeCNT, Activity.uuidPost, Activity.id, sum(CASE WHEN Activity.id = 145 then 1 else 0 end) as CurrentUserLiked
FROM Activity Activity
WHERE type = 'like'
GROUP BY Activity.uuidPost) Activity
ON Activity.uuidPost = P.uuid
AND Activity.id = U.id
WHERE A.id = 145)
To get all the posts a given user (id=145) and all the users it follows posts, along with the user details for each post, I would rewrite the query to use union instead of the or, thus simplifying the logic. The 1st select gets the posts of the given user, the 2nd gets the posts of the users it is following:
(SELECT P.id as postid,
P.caption,
P.date,
U.id as userid,
U.fullname,
U.username,
FROM USERS AS U
INNER JOIN Posts AS P ON P.userid = U.id
WHERE U.id = 145)
UNION
(SELECT P.id,
P.caption,
P.date,
U.id,
U.fullname,
U.username,
FROM Activity AS A
INNER JOIN USERS AS U ON A.IdOtherUser=U.id
INNER JOIN Posts AS P ON P.userid = U.id
WHERE A.id = 145)
ORDER BY postid DESC
Assumptions:
Activity.id field represents the user, who follows the other user. If not, you need to change the field name to the appropriate one.
Invented the userid field of Posts table representing the user who posted the post. Pls use the correct field name in its place.

Adding a JOIN to query resulting in a fail

I am trying to add my users table to my existing query so that I can match the users.id with the forum_topics.topic_creator, so I can match those and enable myself to assign that with that users username.
This is my original query.
$query2 = mysqli_query($con,"SELECT t.*, COUNT(p.topic_id)
AS tid2 FROM forum_topics AS t JOIN forum_posts
AS p on t.id = p.topic_id WHERE t.category_id = ".$cid."
GROUP BY t.id DESC")
I then tried doing this..
$query2 =mysqli_query($con,"SELECT t.*, COUNT(p.topic_id)
AS tid2 FROM forum_topics AS t JOIN forum_posts
AS p on t.id = p.topic_id WHERE t.category_id = ".$cid."
INNER JOIN users AS u
ON t.topic_creator = u.id
GROUP BY t.id DESC")
or die ("Query2 failed: %s\n".($query2->error));
I am getting the fail message.
What am I doing wrong?
WHERE clause should come after join:
SELECT t.*, COUNT(p.topic_id) AS tid2
FROM forum_topics AS t JOIN
forum_posts AS p on t.id = p.topic_id INNER JOIN
users AS u ON t.topic_creator = u.id
WHERE t.category_id = ".$cid."
GROUP BY t.id DESC
EDIT:
To select the username as well:
SELECT t.*,u.username, COUNT(p.topic_id) AS tid2
FROM forum_topics AS t JOIN
forum_posts AS p on t.id = p.topic_id INNER JOIN
users AS u ON t.topic_creator = u.id
WHERE t.category_id = ".$cid."
GROUP BY t.id DESC
The WHERE clause has to be placed after the INNER JOIN.
$query2 =mysqli_query($con,"SELECT t.*, COUNT(p.topic_id)
AS tid2 FROM forum_topics AS t
JOIN forum_posts AS p ON t.id = p.topic_id
INNER JOIN users AS u ON t.topic_creator = u.id
WHERE t.category_id = ".$cid."
GROUP BY t.id DESC")
or die ("Query2 failed: %s\n".($query2->error));
Try this
SELECT t.*, COUNT(p.topic_id) AS tid2
FROM forum_topics t
JOIN forum_posts p ON (t.id = p.topic_id )
INNER JOIN users u ON (t.topic_creator = u.id)
WHERE t.category_id = ".$cid."
GROUP BY t.id DESC`

How to JOIN these 3 tables

I have the following JOIN query already done:
$stmt = $cxn->prepare('SELECT p.post_id, p.reply_to, p.parent_id, p.post_path, p.user_id, p.content, p.datetime, p.total_likes, p.total_replies, p.total_reposts, u.username, u.display_name FROM posts p LEFT JOIN users u ON p.user_id = u.user_id WHERE p.user_id IN (SELECT following_id FROM follows WHERE user_id = ?) AND p.removed != 1 ORDER BY p.datetime DESC LIMIT 26');
$stmt->bind_param('i', $user_info[0]);
$stmt->execute();
I have another query that's only purpose is to check if a row exists or not:
$stmt = $cxn->prepare('SELECT COUNT(like_id) FROM likes WHERE post_id = ? AND user_id = ?');
$stmt->bind_param('ii', $row['post_id'], $user_info[0]); // $row['post_id'] is the value of p.post_id from the first query
$stmt->execute();
How would I join the second query into the first one? I've never joined 3 tables so I'm unsure of the procedure.
Thanks.
Joining three tables in a query is like joining two, except... you join three.
Basically it would go something like this:
SELECT p.post_id (...), u.username (...), COUNT(l.like_id) AS nbOfLikes
FROM posts p
LEFT JOIN users u ON p.user_id = u.user_id
LEFT JOIN likes l ON l.post_id = p.post_id AND l.user_id = u.user_id
WHERE p.user_id IN
(SELECT following_id
FROM follows
WHERE user_id = ?)
AND p.removed != 1
ORDER BY p.datetime DESC
LIMIT 26;
-- Actually I think a UNION would perhaps be more adapted to your need concerning the likes table.
If you always have the user_id filled into your table posts and it's a foreign key, avoid to use a left join statement, you can get a better performance using join statement. To join 3 or more tables you can just add the join statement:
SELECT
p.post_id
, p.reply_to
, p.parent_id
, p.post_path
, p.user_id
, p.content
, p.datetime
, p.total_likes
, p.total_replies
, p.total_reposts
, u.username
, u.display_name
FROM posts p
JOIN users u ON p.user_id = u.user_id WHERE p.user_id IN (SELECT following_id FROM follows
JOIN TABLE_2 ON TABLE_2.id = posts.TABLE_id
JOIN TABLE_3 ON TABLE_3.id = posts.TABLE_id
...
WHERE
user_id = ?)
AND p.removed != 1
ORDER BY p.datetime DESC
LIMIT 26

Categories