JOIN query not producing the correct results - php

I have the following query where I am trying to join my profile_img and users table to match the id's in the friends table (friend_one or friend_two) in oder to get their profile image or user information.
As of now, I do not get any errors...just not the correct results I am looking for. There should be two results that show relation to :profile_user... 5 and 2, which would also give ocean and lake for their profile_img.
The parameter :profile_user is equal to 1. :total_status = 2.
I am not sure if my ON clauses are throwing this off or not. I am not sure how to make u.id = to both the friend_one or friend_two.
Does anyone see why this isn't working?
Here is a fiddle
SELECT f.*, u.*, p.*, IFNULL(p.img, 'profile_images/default.jpg') AS img
FROM friends f
JOIN
users u
ON u.id = (f.friend_one or f.friend_two)
LEFT JOIN
profile_img p
ON p.user_id = f.friend_one or f.friend_two and p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id)
WHERE (friend_one = :profile_user or friend_two = :profile_user)
AND status = :total_status
Full code, which is showing 0 results.
$friend_status = 2;
$friend_sql = "
SELECT f.*, u.*, p.*, IFNULL(p.img, 'profile_images/default.jpg') AS img
FROM friends f
JOIN
users u
ON u.id = (f.friend_one or f.friend_two)
LEFT JOIN
profile_img p
ON p.user_id = f.friend_one or f.friend_two and p.id = (select max(p2.id) from profile_img p2 where p2.user_id = p.user_id)
WHERE (friend_one = :profile_user or friend_two = :profile_user)
AND status = :total_status
";
$friend_stmt = $con->prepare($friend_sql);
$friend_stmt->execute(array(':profile_user' => $profile_user, ':total_status' => $friend_status));
$friend_total_rows = $friend_stmt->fetchAll(PDO::FETCH_ASSOC);
$count_total_friend = $friend_stmt->rowCount();
?>
<div id="friend-list-container">
<div id="friend-list-count">Friends <span class="light-gray"><?php echo $count_total_friend; ?></span></div>
<div id="friend-list-image-container">
<?php
foreach ($friend_total_rows as $friend_total_row) {
$friend_1 = $friend_total_row['friend_one'];
$friend_2 = $friend_total_row['friend_two'];
$friend_img = $friend_total_row['img'];
$friend_username = $friend_total_row['username'];
if($friend_1 !== $profile_user) {
echo $friend_1;
echo $friend_img;
echo $friend_username;
}
if($friend_2 !== $profile_user) {
echo $friend_2;
echo $friend_img;
echo $friend_username;
}
}

after I posted the below I realized mysql does not support cte -- here a version without:
SELECT f.*,
u1.*,
u2.*,
p1.*,
p2.*,
IFNULL(p1.img, 'profile_images/default.jpg') AS img1,
IFNULL(p2.img, 'profile_images/default.jpg') AS img2
FROM friends f
LEFT JOIN users u1 ON u1.id = f.friend_one
LEFT JOIN users u2 ON u2.id = f.friend_two
LEFT JOIN (
SELECT user_id, max(id) as mid
FROM profile_img
GROUP BY user_id
) max1 ON u1.user_id = max1.user_id
LEFT JOIN (
SELECT user_id, max(id) as mid
FROM profile_img
GROUP BY user_id
) max2 ON u2.user_id = max2.user_id
LEFT JOIN profile_img p1 ON p1.user_id = f.friend_one and p1.id = max1.mid
LEFT JOIN profile_img p2 ON p2.user_id = f.friend_two and p2.id = max2.mid
WHERE (friend_one = :profile_user or friend_two = :profile_user)
AND status = :total_status
WITH maxImage AS
(
SELECT user_id, max(id) as mid
FROM profile_img
GROUP BY user_id
)
SELECT f.*,
u1.*,
u2.*,
p1.*,
p2.*,
IFNULL(p1.img, 'profile_images/default.jpg') AS img1,
IFNULL(p2.img, 'profile_images/default.jpg') AS img2
FROM friends f
LEFT JOIN users u1 ON u1.id = f.friend_one
LEFT JOIN users u2 ON u2.id = f.friend_two
LEFT JOIN maxImage max1 ON u1.user_id = max1.user_id
LEFT JOIN maxImage max2 ON u2.user_id = max2.user_id
LEFT JOIN profile_img p1 ON p1.user_id = f.friend_one and p1.id = max1.mid
LEFT JOIN profile_img p2 ON p2.user_id = f.friend_two and p2.id = max2.mid
WHERE (friend_one = :profile_user or friend_two = :profile_user)
AND status = :total_status

If you have an "id" column in your friend table that is the same as the column "id" of your user table, i think you should try this
ON u.id = f.id
instead of
ON u.id = (f.friend_one or f.friend_two)

Based on the data in the mentioned SQL Fiddle. Below is the query that i think will help
select
res1.firstname as FriendOneFirstName,
res1.lastname as FriendOneLastName,
res1.img as FriendOneImage,
user1.firstname as FriendTwoFirstName,
user1.lastname as FriendTwoLastName,
pf1.img as FirendTwoProfileImage
from
(select usr.id,usr.firstname,usr.lastname,pf.img,frds.friend_two
from users usr
inner join friends frds on usr.id=frds.friend_one
inner join profile_img pf on usr.id = pf.user_id
) as res1
inner join users user1 on user1.id=res1.friend_two
inner join profile_img pf1 on user1.id=pf1.user_id
order by user1.id;

Related

how to use where condition in both parts of union in mysql

I'm using php and mysql for making a chat application.
I want to use a where condition in both parts of union but this not working
my code is :
$Query = "(SELECT u.userid, u.photo, u.username FROM `last_activity` AS la INNER JOIN user AS u ON la.userid = u.userid LEFT join private_chat pc ON u.userid = pc.sender_id WHERE la.last_activity_date BETWEEN '2020-09-21 10:20:00' AND '2020-09-21 10:30:00' AND u.username like '%amit%' ORDER BY pc.created_date DESC) UNION (SELECT userid, photo, username FROM user u LEFT join private_chat pc ON u.userid = pc.sender_id WHERE u.u_type = '2')";
and i want like and this not works
$Query = "(SELECT u.userid, u.photo, u.username FROM `last_activity` AS la INNER JOIN user AS u ON la.userid = u.userid LEFT join private_chat pc ON u.userid = pc.sender_id) UNION (SELECT userid, photo, username FROM user u LEFT join private_chat pc ON u.userid = pc.sender_id ) WHERE la.last_activity_date BETWEEN '2020-09-21 10:20:00' AND '2020-09-21 10:30:00' AND u.u_type = '2' AND u.username like '%amit%' ORDER BY pc.created_date DESC";
SELECT *
FROM
(
SELECT u.userid, u.photo, u.username, pc.created_date
FROM `last_activity` AS la
INNER JOIN `user` AS u ON la.userid = u.userid
LEFT JOIN private_chat pc ON u.userid = pc.sender_id
WHERE la.last_activity_date BETWEEN '2020-09-21 10:20:00' AND '2020-09-21 10:30:00'
AND u.username LIKE '%amit%'
UNION ALL
SELECT userid, photo, username, pc.created_date
FROM `user` u
LEFT JOIN private_chat pc ON u.userid = pc.sender_id
WHERE u.u_type = '2'
) a
ORDER BY a.created_date DESC;

Display all clients who have booked a room

Subquery returns more than 1 row and this is the error. I want to print all the booked room details showing the client id and the owner id.
$query = "SELECT r.room_id, r.roomsize, r.numberroom, r.price, u.username,
(SELECT u.username FROM room_register r
INNER JOIN user_info u on r.owner_id = u.user_id
INNER JOIN booked b on b.room_id = r.room_id)as owner_name
FROM room_register r INNER JOIN booked b on b.room_id = r.room_id
INNER JOIN user_info u on u.user_id = b.booked_by";
You have too many joins in the subquery:
SELECT r.room_id, r.roomsize, r.numberroom, r.price, u.username,
(SELECT u.username
FROM user_info u
WHERE r.owner_id = u.user_id
) as owner_name
FROM room_register r INNER JOIN
booked b
ON b.room_id = r.room_id INNER JOIN
user_info u
ON u.user_id = b.booked_by;
Or just use two separate JOINs:
SELECT r.room_id, r.roomsize, r.numberroom, r.price, u.username,
uo.username as owner_name
FROM room_register r INNER JOIN
booked b
ON b.room_id = r.room_id INNER JOIN
user_info u
ON u.user_id = b.booked_by LEFT JOIN
user_info uo
ON uo.user_id = r.owner_id

How to get data from table using GROUP BY and ORDER BY keyword?

I have following tables with columns :
1) users
user_id username
2) projects
p_id p_name
3) project_status
psdi p_id cdid cid sid short_list res_sent status_date
4) company
cid company_name
5) status
sid status_name status_order is_cv_sent
6) projects_log
pl_id cdid project_name p_id user_id status date_time
Now, in this projects_log table there are same p_id value exist.
I want to show all unique p_id with latest date_time. as DESC order where pl.cdid = $cdid
I am using following query but can't get the results. It's not showing me all unique p_id as date_time DESC order :(
$get_log = mysqli_query($link, "SELECT
pl.*,
u.username,
p.p_name,
c.company_name,
s.status_name,
ps.*
FROM projects_log AS pl
LEFT JOIN users AS u ON u.user_id = pl.user_id
LEFT JOIN projects AS p ON p.p_id = pl.p_id
LEFT JOIN project_status AS ps ON ps.p_id = pl.p_id
LEFT JOIN company AS c ON c.cid = ps.cid
LEFT JOIN status AS s ON s.sid = ps.sid
WHERE pl.cdid = '$cdid' GROUP BY pl.p_id
ORDER BY pl.pl_id DESC ");
Using below query you will able to achieve group by p_id and will able to get values of max date_time row.
$get_log = mysqli_query($link, "SELECT
pl.*,
u.username,
p.p_name,
c.company_name,
s.status_name,
ps.*
FROM (
select MAX(date_time) as MaxDateTime,p_id from projects_log group by p_id
) as mpl join projects_log AS pl on mpl.MaxDateTime = pl.date_time and mpl.p_id = pl.p_id
LEFT JOIN users AS u ON u.user_id = pl.user_id
LEFT JOIN projects AS p ON p.p_id = pl.p_id
LEFT JOIN project_status AS ps ON ps.p_id = pl.p_id
LEFT JOIN company AS c ON c.cid = ps.cid
LEFT JOIN status AS s ON s.sid = ps.sid
WHERE pl.cdid = '$cdid'
ORDER BY pl.pl_id DESC ");

How can I combine 2 complex mysql queries

So I have two MySQL queries that if I had the knowledge to combine I would but I don't so that's why I turned to "SO", and in that case I haven't tried anything because its out of my scope. I want to combine all in one query and if that's not possible please let me know.
Query one "This selects all of your friends posts including yours":
"SELECT b.*, c.photo, d.name, e.status
FROM post b
INNER JOIN profile c
INNER JOIN user d
INNER JOIN user_friendship e
ON b.from_user = c.user_id
AND b.from_user = d.id
AND e.friend_id = b.from_user
WHERE e.status = :status
AND e.user_id = :id
ORDER BY b.id DESC LIMIT 20"
Query two "This selects all of the people your following posts":
"SELECT b.*, c.photo, d.name, e.status
FROM post b
INNER JOIN profile c
INNER JOIN user d
INNER JOIN user_follower e
ON b.from_user = c.user_id
AND b.from_user = d.id
AND e.to_id = b.from_user
WHERE e.status = :status
AND e.who_id = :id
ORDER BY b.id DESC LIMIT 20"
I have combined these but with php alone. I'd like to combine both in one single MySQL query. Thanks in advance
SELECT *
FROM
(SELECT b.*,
c.photo,
d.name,
e.status
FROM post b
INNER JOIN profile c
INNER JOIN USER d
INNER JOIN user_friendship e ON b.from_user = c.user_id
AND b.from_user = d.id
AND e.friend_id = b.from_user
WHERE e.status = :status
AND e.user_id = :id LIMIT 20
UNION SELECT b.*,
c.photo,
d.name,
e.status
FROM post b
INNER JOIN profile c
INNER JOIN USER d
INNER JOIN user_follower e ON b.from_user = c.user_id
AND b.from_user = d.id
AND e.to_id = b.from_user
WHERE e.status = :status
AND e.who_id = :id LIMIT 20 ) MainQuery
ORDER BY id DESC
SELECT b.*, c.photo, d.name, e.status, "P"
FROM post b
INNER JOIN profile c
INNER JOIN user d
INNER JOIN user_friendship e
ON b.from_user = c.user_id
AND b.from_user = d.id
AND e.friend_id = b.from_user
WHERE e.status = :status
AND e.user_id = :id
ORDER BY b.id DESC LIMIT 20
UNION
SELECT b.*, c.photo, d.name, e.status, "F"
FROM post b
INNER JOIN profile c
INNER JOIN user d
INNER JOIN user_follower e
ON b.from_user = c.user_id
AND b.from_user = d.id
AND e.to_id = b.from_user
WHERE e.status = :status
AND e.who_id = :id
ORDER BY b.id DESC LIMIT 20
With the extra column you can see where the row is coming from (P = post, F = following)
Keep in mind that union will remove duplicate rows. If you want to see all rows use UNION ALL

Yii CDbCommandBuilder query

I'm trying to perform a query in Yii with CDbCommandBuilder so I can have the resultset in an array.
Problem is that I don't understand how to convert my SQL (pgsql) to the Yii CDbCommandBuilder syntax. Mainly my problem is with nested joins.
The query:
SELECT p.id
up.id as fid,
sum(CASE
WHEN v1.count>v2.count THEN v2.count
ELSE v1.count
END
) as res
FROM product as v1
INNER JOIN (
SELECT p_id, count
FROM product
WHERE user_id = {$user_id}) as v2 on v1.p_id = v2.p_id and v1.user_id <> {$user_id}
RIGHT JOIN users as p on p.id = v1.user_id
INNER JOIN uf on uf.friend_id = p.id and uf.user_id = {$user_id} and is_active = true
INNER JOIN up on up.user_id = p.id and is_active = true
GROUP BY p.id, up.id
ORDER BY res desc
Can anyone help?
Thanks
$sql = "SELECT p.id
up.id as fid,
sum(CASE
WHEN v1.count>v2.count THEN v2.count
ELSE v1.count
END
) as res
FROM product as v1
INNER JOIN (
SELECT p_id, count
FROM product
WHERE user_id = :user_id) as v2 on v1.p_id = v2.p_id and v1.user_id <> :user_id
RIGHT JOIN users as p on p.id = v1.user_id
INNER JOIN uf on uf.friend_id = p.id and uf.user_id = :user_id and is_active = true
INNER JOIN up on up.user_id = p.id and is_active = true
GROUP BY p.id, up.id
ORDER BY res desc";
$params = array(':user_id' => $user_id);
$aArrayOfRows = Yii::app()->db->createCommand($sql)->queryAll(true, $params);

Categories