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
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 3 tables Order, CheckoutStatus, and Statuses. There is a foreign key in Order and CheckoutStatus that references the Statuses table.
I need to join CheckoutStatus to Order linked by the PO column and I need to join Statuses to Order and to CheckoutStatus.
Here is the data in the tables
Order table
`PO` = 123456
foreign key `Statuses_id` = 2
CheckoutStatus
`PO` = 123456
foreign key `Statuses_id` = 0
Statuses
`id` 0 = Complete
`id` 2 = Completed
How do I write my SQL statement so that I can have a result like this.
Order
123456
Completed
CheckoutStatus
123456
Complete
This SQL statement I'm using does not display anything unless I remove one of the JOIN Statuses section of the statement.
SELECT * FROM `Order` JOIN `Statuses` ON Statuses.id = Order.Statuses_id JOIN `CheckoutStatus` ON Order.PO = CheckoutStatus.PO JOIN `Statuses` ON Statuses.id = CheckoutStatus.Statuses_id
You have two JOINs on table Statuses. You need to use table aliases to distinguish the two relationships :
SELECT
`Order`.PO,
s1.Status,
s2.Status
FROM
`Order`
JOIN `Statuses` s1 ON s1.id = Order.Statuses_id
JOIN `CheckoutStatus` ON Order.PO = CheckoutStatus.PO
JOIN `Statuses` s2 ON s2.id = CheckoutStatus.Statuses_id
this can get a little bit confusing you can split the query and on the basis of its fetched result, you can fetch further more
$sql4 = "SELECT * FROM `Order` JOIN `Statuses` ON Statuses.id =
Order.Statuses_id JOIN `CheckoutStatus` ON somthing"
$result4 = mysqli_query($conn, $sql4);
if (mysqli_num_rows($result4) > 0)
{
while($row3 = mysqli_fetch_assoc($result4))
{
$sql5='SELECT * FROM //the result of before joining other two '
}
}
something like this
I have this Query to call information form two table.
DB::get("SELECT friends. * , (SELECT `login` FROM `users` WHERE `users`.`id` = friends.`user_id`) AS `login` FROM `friends` WHERE `id_user`='" . $this->user['id'] . "' ORDER BY `id` DESC LIMIT ")
So if user is on friends list show username , i would like to get username and avatar. Avatar row is avatar .
I try with this.
DB::get("SELECT friends. * , (SELECT `login`, `*avatar*` FROM `users` WHERE `users`.`id` = friends.`user_id`) AS `login` FROM `friends` WHERE `id_user`='" . $this->user['id'] . "' ORDER BY `id` DESC LIMIT ")
And give me the error
SQLSTATE[21000]: Cardinality violation: 1241 Operand should contain 1 column(s)
where is the mistake?
First of all you should use Prepared Statement and Second, you can't write inline view, which has two columns
SELECT friends. * , (SELECT `login`, `*avatar*` FROM ..
instead you should use JOIN, which might be efficient than current approach and more readable.
You need to use JOIN, e.g.:
SELECT f.*, u.*
FROM friends f JOIN users u ON f.user_id = u.id
WHERE f.id_user = <your_id>
ORDER BY id DESC LIMIT <your_limit>;
I have a table which includes 130k+ rows. I want to list most liked users.
I try lots of queries but I didnt get result.
table 1 : "users" / user_id / user_name
table 2 : "likes" / datetime / user_id
$query = mysql_query("SELECT COUNT(*) FROM
(
SELECT DISTINCT a.user_id, b.user_id,b.user_name
FROM dbo.likes AS a
INNER JOIN dbo.users AS b
ON a.user_id= b.user_id
) AS subquery;");
and
while($row = mysql_fetch_array($query))
{
echo $row=['user_name'].'-'.$row=['count(*)'];
}
select user_name, count(user_name)
from users, likes
where users.user_id = likes.user_id
group by user_name
Yes so im building an query from the advanced search form.
I have this:
$query = "SELECT * FROM users WHERE 1 ";
$query .= "AND sex = '$sex' ";
for now, next im going to have AND birthday.. but then i dont know how to do it, because users birthday is stored in users_profile
So please correct me, how can i:
$query .= "AND birthday in users_profile = '1'";
Is this possible even, or should i reconstruct it and put birthday in users instead..
update:
in users, the id column there, is binded with users_profileĀ“s uID.
So in users_profileĀ“s uID column, there is the users id.
I assume your users_profile table is linked to the users table?
SELECT u.*, up.birthday
FROM users u
INNER JOIN users_profile up
ON u.user_id = up.user_id
WHERE sex = '$sex'
Here an Inner Join is used. The reason we can use u instead of users and up instead of users_profile is because we have set up the aliases "users u" and "users_profile up"
You need to look at the syntax for JOIN.
You need a way to join individual related rows in the two tables, something like:
SELECT u.* FROM users u, users_profile p
WHERE u.sex = 'M'
AND p.birthday = '1'
AND u.userid = p.userid;
I don't understand why you have separate tables for user and for users_profile, but you need to JOIN the two tables:
SELECT U.*
FROM users U
LEFT JOIN users_profile P
ON P.uID = U.uID
AND P.birthday = '1'
WHERE U.sex = '$sex'
Very possible, given you have the foreign key to the users_profile table.
Let's say the primary key in the users table is named 'id', and the users_profile table contain a field called 'uid' which point to the users table, you'd normally create the query like this:
SELECT * FROM users u, users_profile p WHERE u.id = p.uid
AND u.sex = '$sex' AND u.birthday = 1