I have this comment table where users can post comment as well as guest, i can fetch users comments like this
SELECT `comments`.`user_id`, `comments`.`pubdate`, `comments`.`comment`,
`comments`.`guest_name`,
`comments`.`id`,
`users`.`username`,
FROM (`comments`)
JOIN `users` ON `comments`.`user_id` = `users`.`user_id`
WHERE `item_id` = '64' AND `section` = 'blog'
problem is guest users don't have user id hence thier id goes to db as 0 so it is not displayed, how can i show comments of both users and guest ?
You should use LEFT JOIN
SELECT `comments`.`user_id`, `comments`.`pubdate`, `comments`.`comment`,
`comments`.`guest_name`,
`comments`.`id`,
`users`.`username`,
FROM `comments`
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`user_id`
WHERE `item_id` = '64' AND `section` = 'blog'
If there's no matching user for comments.user_id, then users.username will be NULL.
use a left join :
SELECT `comments`.`user_id`, `comments`.`pubdate`, `comments`.`comment`,
`comments`.`guest_name`,
`comments`.`id`,
`users`.`username`,
FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`user_id`
WHERE `item_id` = '64' AND `section` = 'blog'
Do a LEFT JOIN, not a simple one.
SELECT `comments`.`user_id`, `comments`.`pubdate`, `comments`.`comment`,
`comments`.`guest_name`, `comments`.`id`, `users`.`username`
FROM `comments`
LEFT JOIN `users` ON (`comments`.`user_id` = `users`.`user_id`)
WHERE `item_id` = '64' AND `section` = 'blog'
Related
comment table and post table both has column named user_id
I cannot specify both table's user_id
for using some if else condition later I need both the user_id as a different name (I'm trying to use AS).
I tried different way but query not working:
$sql="SELECT `post_id`, `comment_id`, `comment`, `user_id`, `username`,
`is_marked` `post`.`user_id` AS `p_uid` FROM `comment` INNER JOIN `user` ON
`comment`.`user_id` = `user`.`id` INNER JOIN `post` ON
`user`.`id`=`post`.`user_id` ORDER BY `comment_id` DESC";
$result = mysqli_query($con, $sql);
if ($result) {
while ($row=mysqli_fetch_assoc($result)) {
$post_user_id = $row['p_uid'];
You could alias table name with other name and get column. View example:
SELECT C.comment_id, U.user_id
FROM comment C INNER JOIN user u ON C.user_id = U.id
I would do:
SELECT c.post_id,
c.comment_id,
c.comment,
c.user_id AS c_uid,
c.username,
c.is_marked,
p.user_id AS p_uid
FROM comment c
INNER JOIN user u ON c.user_id = u.id
INNER JOIN post p ON c.user_id = p.id
ORDER BY c.comment_id DESC
Define aliases for the tables, and the selected fields. It makes it simpler to read than putting the table names all the time.
In your PHP you can then reference $row['c_uid'] or $row['p_uid'].
I have a code :
$id=implode(",",$selected);
$query = "SELECT u.id, p.brand, n.number FROM `user` u
LEFT OUTER JOIN `phone` p ON u.id = p.id LEFT OUTER JOIN `number` n
ON p.id = n.id WHERE u.id in ($id)";
Where $selected is an array array(1,2,3). But when i run it, it appears this notice :
Unknown column '1' in 'where clause'
How to handle this problem? Thank you
Here you can do it like :
$id = implode("','",$selected);
This query will run :
$query = "SELECT u.id, p.brand, n.number FROM `user` u LEFT OUTER JOIN `phone` p ON u.id = p.id LEFT OUTER JOIN `number` n
ON p.id = n.id WHERE u.id in ('$id')";
I'm trying to make a internal web based message system, with a *amp system, primarily for learning purposes. I don't know if this is a trivial topic, but I'm having difficulties so please bear with me.
The goal is to list all the contacts ordered by the last message sent / received.
Currently without sorting it the SQL looks like this
$query = "SELECT username, user.id as user_id,
(SELECT COUNT(message_read)
FROM message_user
WHERE message_read = 0
AND sent_id = user_id
AND receive_id = {$userId}) as unread
FROM user
WHERE user.id IN
(SELECT contact_id FROM allowed_contact WHERE user_id = {$userId})
;";
The structure of the tables are:
The user table has an id,
That links to the message_user table which has a sent_id and a receive_id,
The message_user has a message_id that corresponds to the message.id,
The message table has a timestamp.
I would like this to be done in SQL but if it comes down to PHP I resign to resort to that.
This works.
SELECT `u`.`id` AS user_id, username,
(SELECT COUNT(message_user.message_read)
FROM message_user
WHERE message_user.message_read = 0
AND sent_id = user_id
AND receive_id = {$userId}) as unread
FROM `user` AS `u`
LEFT JOIN `message_user` AS `mu`
ON
(CASE WHEN `u`.`id` != {$userId}
THEN `u`.`id` = `mu`.`sent_id`
WHEN `mu`.`sent_id` = {$userId} AND `mu`.`receive_id` = {$userId}
THEN `u`.`id` = `mu`.`sent_id`
END)
OR
(CASE WHEN `u`.`id` != {$userId}
THEN `u`.`id` = `mu`.`receive_id`
END)
LEFT JOIN `message` AS `m` ON `m`.`id` = `mu`.`message_id`
WHERE u.id IN
(SELECT contact_id FROM allowed_contact WHERE user_id = {$userId})
GROUP BY u.id
ORDER BY MAX(`m`.`timestamp`) DESC;
This broke down the problem I was having.
#Andreas thanks for time and help.
Use 2 LEFT JOIN with a DISTINCT (untested):
SELECT DISTINCT `u`.`id`
FROM `user` AS `u`
LEFT JOIN `message_user` AS `mu` ON `u`.`id` = `mu`.`sent_id` OR `u`.`id` = `mu`.`receive_id`
LEFT JOIN `message` AS `m` ON `m`.`id` = `mu`.`message_id`
ORDER BY `m`.`timestamp` DESC;
I'm new to mysql and I have a problem with selecting data from mysql database:
$post_id = 3;
$current_user_id = 1;
$query = "SELECT `comments`.*, `users`.`username`, `users`.`image` FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`id`
WHERE `comments`.`post_id` = '$post_id'
AND `comments`.`status` = 1
AND `users`.`status` = 1
ORDER BY `comments`.`date` desc";
This select, selects all approved comments from database, but also, in this select, I need all unapproved comments of $current_user_id,
Result must look like:
[all approved post comments] + [all unapproved post comments of $current_user_id]
not sure if this will really work, but just give a try and see. I can't test the query since we don't have the schema.
SELECT `comments`.*, `users`.`username`, `users`.`image` FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`id`
WHERE `comments`.`post_id` = '$post_id'
AND (
(`comments`.`status` = 1 AND `users`.`status` = 1)
OR
( `comments`.`status` = 0 AND `users`.`id`= '$current_user_id' )
)
ORDER BY `comments`.`date` desc
What I thought is select all the approved comments OR ( comments that are not approved, but from this user ). You might have to alter the query till you get what you really needed, I'm just giving you the idea, not the exact query. Hope this will help you.
SELECT `comments`.*, `users`.`username`, `users`.`image` FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`id`
WHERE `comments`.`post_id` = '$post_id'
AND `comments`.`status` = 1
AND `users`.`status` = 1
UNION ALL
SELECT `comments`.*, `users`.`username`, `users`.`image` FROM (`comments`)
LEFT JOIN `users` ON `comments`.`user_id` = `users`.`id`
WHERE `comments`.`post_id` = '$post_id'
AND `comments`.`status` = 0
AND `users`.`id` = '$current_user_id'
ORDER BY `comments`.`date` desc
I had the following code, which uses 2 queries to get the friends list.
<?php
$getFriendStatement = <<<EOS
SELECT DISTINCT u.username
FROM users AS u
INNER JOIN test_friends AS f on u.Id = f.user_id
WHERE f.friend_id = ?
&& f.active=1
EOS;
$getFriendQuery = $mysqli->prepare($getFriendStatement);
$getFriendQuery->bind_param('i', $userID);
$getFriendQuery->execute() or die ($mysqli->error);
$getFriendResult = $getFriendQuery->get_result();
$friendName = "";
while ($getFriendFetch = $getFriendResult->fetch_assoc()) {
$friendName .= $getFriendFetch['username'] . ", ";
}
$getFriendStatement = <<<EOS
SELECT u.username
FROM users AS u
INNER JOIN test_friends AS f ON u.id = f.user_id
WHERE (f.friend_id = ? AND active=1)
OR (f.user_id = ? AND active=1)
EOS;
$getFriendQuery = $mysqli->prepare($getFriendStatement);
$getFriendQuery->bind_param('ii', $userID, $userID);
$getFriendQuery->execute() or die ($mysqli->error);
$getFriendResult = $getFriendQuery->get_result();
while ($getFriendFetch = $getFriendResult->fetch_assoc()) {
$friendName .= $getFriendFetch['username'] . ", ";
}
if (!empty($friendName)){
echo "Your friends: " . $friendName ;
} else {
echo "You do not have any friends yet";
}
?>
Is there a way to execute just 1 query to retrieve all friends?
Schema information: the above relies on two tables, users and test_friends:
CREATE TABLE users (
`id` int(11),
`username` varchar(256)
);
CREATE TABLE test_friends (
`user_id` int(11),
`friend_id` int(11),
`active` tinyint,
FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (`friend_id`) REFERENCES `users` (`id`)
ON UPDATE CASCADE ON DELETE CASCADE
);
You should be able to do a union to do both queries in one. Your SQL will look like this:
SELECT U.username
FROM users AS U
INNER JOIN test_friends AS F
ON U.Id = F.user_id
WHERE F.friend_id = '{$userID}'
AND F.active = 1
UNION
SELECT u.username
FROM users u
INNER JOIN test_friends f
ON u.id = f.user_id
WHERE ( f.friend_id = '{$userID}'
AND active = 1 )
OR ( f.user_id = '{$userID}'
AND active = 1 )
It will also remove duplicates for you automatically, as if you included DISTINCT on the whole lot. (You do "UNION ALL" if you don't want that.)
Also, if you want to order the results, add "ORDER BY 1 ASC" on the end. You can only use result set column numbers in the ORDER BY clause with unions.
Union queries only work if the number and types of the columns returned in the result set by each sub-query are the same.
Aside: Your first query appears to be a subset of the second query, so you really only need to so the second query. I've left it as is as a demonstration of how to do unions, but you don't really need to in this case.
You can perform a UNION between the two queries. For example:
SELECT username FROM users WHERE username like '%billy%'
UNION
SELECT username FROM users WHERE username like '%bob%'
will return all users with names like billy or bob. Combining your entire two queries above with a UNION should work.
so you want names of $userID's friends AND names of users who have $userID as friend ?
how about
select distinct U.username
from users U
inner join test_friends f
on
(f.user_id = U.id AND f.friend_id={userID}) OR
(f.friend_id=U.id AND f.user_id={userID})
where active=1
As your first query appears to be a subset of your second query, you should only need to execute the second query.
I assume that in the Test_Friends table the user_id field represents the userid of the user and the friend_id field represents the userid of the user's friend.
If this is the case then you can execute the query:
SELECT DISTINCT U.username
FROM Test\_Friends F
INNER JOIN Users U ON F.friend\_id = U.user\_id
WHERE
F.user\_id = '{$userID}' AND
F.active = 1