This is my query:
SELECT u.ProfilePic AS FriendPic, u.UserName AS FriendName, m.*
FROM (SELECT PhotographerId
FROM Messages
WHERE UserId=? OR PhotographerId=?
GROUP BY PhotographerId
) AS m JOIN
User AS u
ON u.UserId = m.PhotographerId;
I'm trying to make SQL query from table, - get last messages from all pairs of users with user ? as sender or recipient, and join them with users table to get names. I've managed to create something like this, but still want to ask if there is more simple
i want to fetch the photogrpher name, profile pic and last message of every user as we see in inbox..
table
user: profile pic, username,user_id
message: userid, photographerid, message, timestamp
Try this:
SELECT m.userid AS 'User id', u1.profile_pic AS 'User pic', u1.username AS 'User name`,
m.photographerid AS 'Photographer id', u2.profile_pic AS 'Photographer pic',
u2.username AS 'Photographer name`,
m.message, m.timestamp
FROM message m JOIN user u1 ON m.userid = u1.user_id
JOIN user u2 ON m.photographerid = u2.user_id
ORDER BY m.timestamp DESC LIMIT 1;
Update:
You can get latest messages for a user with the below query:
SELECT m.userid, a.photographerid, m.message, a.timestamp
FROM message m
JOIN (SELECT photographerid, MAX(timestamp) as timestamp
FROM message where userid = ?
GROUP BY photographerid
) a
ON m.photographerid = a.photographerid and m.timestamp = a.timestamp
WHERE m.userid = ?
UNION
SELECT a.userid, m.photographerid, m.message, a.timestamp
FROM message m
JOIN (SELECT userid, MAX(timestamp) as timestamp
FROM message where photographerid = ?
GROUP BY userid
) a
ON m.userid = a.userid and m.timestamp = a.timestamp
WHERE m.photographerid = ?
Once you get the message, you can JOIN the output of this query with user table to get the values of other columns, e.g.:
SELECT m.userid AS 'User id', u1.profile_pic AS 'User pic', u1.username AS 'User name`,
m.photographerid AS 'Photographer id', u2.profile_pic AS 'Photographer pic',
u2.username AS 'Photographer name`,
m.message, m.timestamp
FROM (
SELECT m.userid, a.photographerid, m.message, a.timestamp
FROM message m
JOIN (SELECT photographerid, MAX(timestamp) as timestamp
FROM message where userid = ?
GROUP BY photographerid
) a
ON m.photographerid = a.photographerid and m.timestamp = a.timestamp
WHERE m.userid = ?
UNION
SELECT a.userid, m.photographerid, m.message, a.timestamp
FROM message m
JOIN (SELECT userid, MAX(timestamp) as timestamp
FROM message where photographerid = ?
GROUP BY userid
) a
ON m.userid = a.userid and m.timestamp = a.timestamp
WHERE m.photographerid = ?
) m JOIN user u1 ON m.userid = u1.user_id
JOIN user u2 ON m.photographerid = u2.user_id;
Related
I have a table called last_msg, in there i store the last mensage from a private chat between two users, and i update the column from and to when I send a new mensage. I use this table to show a list of mensages like facebook. I also use this table to another things, so i would rather fix the problem described as bellow.
Because of the ON users.user_id = last_msg.from i get data only from who is sending the mensage, this was the best i got... This is my current sql:
SELECT `last_msg`.`msg`, `last_msg`.`from`, `users`.`username`, `users`.`avatar`
FROM `last_msg`
INNER JOIN `users`
ON `users`.`user_id` = `last_msg`.`from`
WHERE `last_msg`.`to` = :user_id_logged OR `last_msg`.`from` = :user_id_logged_2
On the INNER JOIN users I want to get data only from the other user that i'm talking to in the chat, and the data from last_msg can be from both sender and receiver, as the facebook does.
So i tried:
SELECT `last_msg`.`msg`, `last_msg`.`from`, `users`.`username`, `users`.`avatar`
FROM `last_msg`
INNER JOIN `users`
ON `users`.`user_id` != :user_logged
WHERE (`last_msg`.`to` = :user_logged_2 OR `last_msg`.`from` = :user_logged_3)
But it did not work, it's returning a list of all users in the table users. Any suggestions about how can i fix it?
You can try joining the users table two times, one for the from user and the other for the to user like shown below, also note you need to use LEFT Join in order to get all from and to users.
SELECT `last_msg`.`msg`, `last_msg`.`from`, `FromUser`.`username`, `FromUser`.`avatar`,`ToUser`.`username`,`ToUser`.`avatar`
FROM `last_msg`
LEFT JOIN `users` as `FromUser`
ON `FromUser`.`user_id` = `last_msg`.`from`
LEFT JOIN `users` as `ToUser`
ON `ToUser`.`user_id` = `last_msg`.`to`
WHERE `last_msg`.`to` = :user_id_logged OR `last_msg`.`from` = :user_id_logged_2";
Updated Code
SELECT `last_msg`.`msg`, `last_msg`.`from`, `users`.`username`, `users`.`avatar`
FROM `last_msg`
INNER JOIN `users`
ON `users`.`user_id` =`last_msg`.`to`
WHERE `last_msg`.`from`= :user_logged
UNION
SELECT `last_msg`.`msg`, `last_msg`.`to`, `users`.`username`, `users`.`avatar`
FROM `last_msg`
INNER JOIN `users`
ON `users`.`user_id` =`last_msg`.`from`
WHERE `last_msg`.`to`= :user_logged
This is how to get the messages last sent to you:
SELECT msg, `from` as other_user_id
FROM last_msg
WHERE `to` = :user_logged;
If you also want the messages you last sent:
SELECT msg, `to` as other_user_id
FROM last_msg
WHERE `from` = :user_logged;
You say you store only the one last message per chat. I read this as for users A and B there will only be one row in the table (either the last message A sent to B or the last message B sent to A). So you can just combine the two queries and still show only one last message per chat.
SELECT m.msg, u.user_id, u.username, u.avatar
FROM
(
SELECT msg, `from` as other_user_id
FROM last_msg
WHERE `to` = :user_logged
UNION ALL
SELECT msg, `to` as other_user_id
FROM last_msg
WHERE `from` = :user_logged
) m
JOIN users u ON u.user_id = m.other_user_id;
An alternative to UNION ALL is a join and CASE WHEN:
SELECT m.msg, u.user_id, u.username, u.avatar
FROM last_msg m
JOIN users u
ON u.user_id = CASE WHEN :user_logged = m.from THEN m.to ELSE m.from END as other_user_id
WHERE :user_logged IN (m.from, m.to)
This ON clause can also be written as
ON (u.user_id = m.from AND :user_logged = m.to)
OR (u.user_id = m.to AND :user_logged = m.from)
or
ON u.user_id IN (m.from, m.to) AND u.user_id <> :user_logged;
by the way. Pick what you like better.
And here is a way to use the user ID parameter only once in the query:
SELECT m.msg, u.user_id, u.username, u.avatar
FROM (select :user_logged as user_id) myself
JOIN last_msg m ON myself.user_id IN (m.from, m.to)
JOIN users u ON u.user_id IN (m.from, m.to) AND u.user_id <> myself.user_id;
I am using Laravel 5.1 in my application. My MySQL query is
"Select * from "
. "(Select u.* from "
. "( "
. "SELECT u2.id as user_id, u2.fname as fname, u2.lname as lname, u2.uname as uname, u2.email as email, u2.address as address, u2.city_id as city_id, u2.website as website FROM users u1, users u2 where u1.city_id = u2.city_id && u1.id = '$this->current_user_id' )
u left join follows f on u.user_id = f.following_id where f.following_id is null
UNION
Select uu.id as user_id, uu.fname as fname, uu.lname as lname, uu.uname as uname, uu.email as email, uu.address as address, uu.city_id as city_id, uu.website as website from users uu where uu.id in (Select u.user_id from (SELECT user_id FROM reviews group by user_id order by count(user_id) desc5
) u left join follows f on u.user_id=f.following_id where f.following_id is null
)
)
T LIMIT 5"
How can I convert it into Laravel Eloquent?
Is that query functionally identical to this one:
SELECT u2.id user_id
, u2.fname
, u2.lname
, u2.uname
, u2.email
, u2.address
, u2.city_id
, u2.website
FROM users u1
JOIN users u2
ON u2.city_id = u1.city_id
LEFT
JOIN follows f
ON f.following_id = u.user_id
WHERE f.following_id is null
UNION
SELECT uu.id user_id
, uu.fname
, uu.lname
, uu.uname
, uu.email
, uu.address
, uu.city_id
, uu.website
FROM users uu
JOIN
( SELECT r.user_id
FROM reviews r
LEFT
JOIN follows f
ON f.following_id = r.user_id
WHERE f.following_id IS NULL
GROUP
BY user_id
ORDER
BY COUNT(user_id) DESC
LIMIT 5
) x
ON x.user_id = uu.id;
?
What am I doing wrong here? Trying to use a subquery as my FROM to ensure all joined tables are joined on the correct set.
SELECT
active_users.username as username,
active_users.computer_name as computer_name,
alert.cnt as alerts
FROM
(SELECT
computer_name,
username
FROM computers
INNER JOIN users
on users.computer_id = computers.computer_id
WHERE computers.account_id = :cw_account_id AND computers.status = :cw_status
) AS active_users
LEFT JOIN
(SELECT
user_id,
count(*) as cnt
from logs
group by user_id
) AS alert
on alert.user_id = active_users.user_id
You need to select user_id in the first subquery:
SELECT active_users.username as username, active_users.computer_name as computer_name,
alert.cnt as alerts
FROM (SELECT user_id, computer_name, username
FROM computers INNER JOIN
users
on users.computer_id = computers.computer_id
WHERE computers.account_id = :cw_account_id AND computers.status = :cw_status
) active_users LEFT JOIN
(SELECT user_id, count(*) as cnt
from logs
group by user_id
) alert
on alert.user_id = active_users.user_id;
I have this query to get information from two tables:
SELECT u.username, u.id,
SUM(t.result = 1) AS winnings,
SUM(t.result = 2) AS loses
FROM users u
LEFT JOIN tahminler t ON u.id = t.user_id
GROUP BY u.id
I want to get comments_no for each user from another table; something like this:
SELECT u.username, u.id,
SUM(t.result = 1) AS winnings,
SUM(t.result = 2) AS loses,
f1.comments_no
FROM users u
LEFT JOIN tahminler t ON u.id = t.user_id
INNER JOIN (select count(distinct match_static_id) as comments_no,user_id from comments where user_id = "here is my problem")
GROUP BY u.id
Is it possible to but the value of u.id in the where user_id = u.id.
Briefly How to get the comments_no for each user in my query.?
Use a GROUP BY in the sub query:-
SELECT u.username, u.id,
SUM(t.result = 1) AS winnings,
SUM(t.result = 2) AS loses,
f1.comments_no
FROM users u
LEFT JOIN tahminler t ON u.id = t.user_id
INNER JOIN (select user_id, count(distinct match_static_id) as comments_no from comments GROUP BY user_id) f1
ON u.id = f1.user_id
GROUP BY u.id
I've searched on stackoverflow already, but the existing threads did not help me, so im posting this.
My database schema:
user: user_id, displayname
message: id, sender_id, receiver_id, message, dateSent
What i want:
Show me a list of the latest message from each user WHERE receiver_id = 4
What i already tried:
MYSQL select newest posts from tables
query to get last message only from all users
Still can't solve my problem :(
Try this:
SELECT
u1.displayname AS SenderName,
m.date_sent,
...
FROM messages AS m1
INNER JOIN users AS u1 ON m1.sender_id = u1.id
(
SELECT sender_id, MAX(dateSent) MaxDate
FROM messages
GROUP BY sender_id
WHERE receiver_id = 4
) AS m2 ON m1.sender_id = m2.sender_id
AND m1.datesent = m2.maxdate
SELECT u.user_id, u.displayname, m.message
FROM user u
INNER JOIN
(SELECT id, sender_id, receiver_id, message, MAX(dateSent) AS mdate
FROM message msg
WHERE receiver_id = 4
GROUP BY sender_id
) as m
ON u.user_id = m.sender_id AND u.dateSent = m.mdate
HTH
SELECT m.id, MAX as mDate, m.sender_id, u.displayname
FROM message m
LEFT JOIN user u ON u.user_id = m.sender_id
WHERE m.receiver_id = 4
GROUP BY sender_id