how to find last message from message table and also find users - php

This is my User table
This is my Message table
And tHis is my Listing Table
Now I get successfully get the last message with this query
enter code here
$coreQueryUser = $this->Message->query('
select m.*
from
messages m
inner join (
select max(id) as maxid
from messages
where messages.list_id = 3
group By (if(sender_id > reciever_id, sender_id, reciever_id)),
(if(sender_id > reciever_id, reciever_id, sender_id))
) t1 on m.id=t1.maxid
');
when i run this query it gives me following output:-
enter code here
<pre>Array
(
[0] => Array
(
[m] => Array
(
[id] => 2
[sender_id] => 10
[reciever_id] => 21
[list_id] => 3
[message] => hello sir
[add_date] => 2016-09-25 08:24:38
[is_check] => 0
)
)
[1] => Array
(
[m] => Array
(
[id] => 7
[sender_id] => 10
[reciever_id] => 22
[list_id] => 3
[message] => hmm
[add_date] => 2016-09-27 00:00:00
[is_check] => 0
)
)
)
Now you see in the output in first array sender_id =10 and reciver_id = 21
and list_id = 3
List is created by user whose id is 10. in the output i want to fetch the User data whose user id 21. Remember that when reciever send the message to sender the ids are interchanging. in that case i also want the data of whose user id is 21
Please help me:(

Finallly i find the solution of my own
enter code here
$coreQueryUser = $this->Message->query('
select m.* ,u.*
from
messages m
inner join (
select max(id) as maxid
from messages
where messages.list_id = " '. $data['list_id'] .'"
group By (if(sender_id > reciever_id, sender_id, reciever_id)),
(if(sender_id > reciever_id, reciever_id, sender_id))
) t1 on m.id=t1.maxid
join
users u ON u.id = (CASE WHEN m.sender_id = 10
THEN m.reciever_id
ELSE m.sender_id
END)
');

Related

select GROUP_CONCAT in mysql

I have two tables:
table1:
id email
1 john#gmail.com
2 doe#gmail.com
table2:
userid key value
1 firstname john
1 phone 112233
2 firstname doe
2 phone 223344
This is mysql query without condition:
SELECT a.*,
b.*,
GROUP_CONCAT(b.key),
GROUP_CONCAT(b.value)
FROM table1 a
LEFT JOIN table2 b ON a.id = b.userid
This is result:
array(
[id] => 1
[email] => john#gmail.com
[userid] => 1
[key] => firstname,phone
[value] => john,112233
)
array(
[id] => 2
[email] => doe#gmail.com
[userid] => 2
[key] => firstname,phone
[value] => doe,223344
)
This is mysql query with condition:
SELECT a.*,
b.*,
GROUP_CONCAT(b.key),
GROUP_CONCAT(b.value)
FROM table1 a
LEFT JOIN table2 b ON a.id = b.userid
WHERE b.key = "firstname"
AND b.value LIKE '%jo%'
And this is result:
array(
[id] => 1
[email] => john#gmail.com
[userid] => 1
[key] => firstname
[value] => john
)
But I want this:
array(
[id] => 1
[email] => john#gmail.com
[userid] => 1
[key] => firstname,phone
[value] => john,112233
)
There any way to do this? thank for any help!
Your queries are lacking the GROUP BY clause to get a row per user. Then use a HAVING clause to make sure the aggregated row includes a firstname '%jo%':
SELECT a.*,
GROUP_CONCAT(b.key),
GROUP_CONCAT(b.value)
FROM table1 a
LEFT JOIN table2 b ON a.id = b.userid
GROUP BY a.id
HAVING sum(b.key = 'firstname'
AND b.value LIKE '%jo%') > 0;
true results in 1, false in 0 in MySQL. So checking whether the sum is greater than zero means checking whether the condition is true at least once.

Order by not working with group by clause

I am using corequery of mysql in cakephp. I want the records in descending order. This is my table structure
enter code here
$coreQueryUser = $this->Message->query(
"select * from messages where messages.list_id = 3
group By (if(sender_id > reciever_id, sender_id, reciever_id)),
(if(sender_id > reciever_id, reciever_id, sender_id))
order by id desc
"
);
I want last message that belongs to (sender_id and reciver_id and viceversa) that belongs to list id 3
when i run this query i get the following output
<pre>Array
(
[0] => Array
(
[messages] => Array
(
[id] => 1
[sender_id] => 21
[reciever_id] => 10
[list_id] => 3
[message] => hello
[add_date] => 2016-09-25 00:00:00
[is_check] => 0
)
)
[1] => Array
(
[messages] => Array
(
[id] => 3
[sender_id] => 22
[reciever_id] => 10
[list_id] => 3
[message] => hello s
[add_date] => 2016-09-25 16:39:41
[is_check] => 0
)
)
)
but i wnat result like that:
Array
(
[0] => Array
(
[messages] => Array
(
[id] => 2
[sender_id] => 10
[reciever_id] => 21
[list_id] => 3
[message] => hello sir
[add_date] => 2016-09-25 00:00:00
[is_check] => 0
)
)
[1] => Array
(
[messages] => Array
(
[id] => 6
[sender_id] => 22
[reciever_id] => 10
[list_id] => 3
[message] => new
[add_date] => 2016-09-25 16:39:41
[is_check] => 0
)
)
)
Can anyone help me :(
The problem is that your query is against the sql standard because you have several fields in the select list that are neither in the group by list, nor are subject of an aggregate function, such as sum(). MySQL unfortunately allows such invalid queries to run under certain sql mode settings (the default settings of the most recent versions of MySQL would prevent such queries from running).
As MySQL documentation on group by clause says (bolding is mine):
If ONLY_FULL_GROUP_BY is disabled, a MySQL extension to the standard
SQL use of GROUP BY permits the select list, HAVING condition, or
ORDER BY list to refer to nonaggregated columns even if the columns
are not functionally dependent on GROUP BY columns. This causes MySQL
to accept the preceding query. In this case, the server is free to
choose any value from each group, so unless they are the same, the
values chosen are indeterminate, which is probably not what you want.
Furthermore, the selection of values from each group cannot be
influenced by adding an ORDER BY clause. Result set sorting occurs
after values have been chosen, and ORDER BY does not affect which
value within each group the server chooses.
You apparently want the latest record (with max(id) for each group. The proper way is to have a subquery that returns the max(id) per group and in the outer query join back to your main table using the ids to get the value of the other fields:
select m.*
from
messages m
inner join (
select max(id) as maxid
from messages
where messages.list_id = 3
group By (if(sender_id > reciever_id, sender_id, reciever_id)),
(if(sender_id > reciever_id, reciever_id, sender_id))
) t1 on m.id=t1.maxid
This code working:
SELECT * FROM generate_invoice
WHERE id IN
(
SELECT max(id) as id
FROM generate_invoice
GROUP by pay_id
ORDER by id DESC
)
How to group by DESC order
Try
SELECT * FROM ( SELECT * FROM generate_invoice ORDER BY id DESC ) AS g GROUP BY g.pay_id
OR
Use this code
SELECT m1.*,m2.* FROM generate_invoice m1 LEFT JOIN generate_invoice m2 ON (m1.pay_id = m2.pay_id AND m1.id < m2.id ) order by m1.id desc

sql join from 3 tables

I have 3 tables
user,
wink,
messages
Im going to clarify what i want because no one seems to understand
SELECT wink.*,user.id,user.points,user.gender,user.firstname,user.email
FROM wink
INNER JOIN user ON
(wink.id_user_from_wink=user.id OR wink.id_user_to_wink=user.id)
WHERE user.id!=?
AND (wink.id_user_from_wink=? OR wink.id_user_to_wink=?)
AND wink.wink_confirmed='1'
This works exactly as i want i to. I get the desired resultset, however now i need to get the last row matching from messages table.
I have tried using LEFT JOIN but it returns to many rows.
I need to return the last matching row for each result i get from the query above
As i said, i have tried:
SELECT wink.*,user.id,user.points,user.gender,user.firstname,user.email
FROM wink
INNER JOIN user ON
(wink.id_user_from_wink=user.id OR wink.id_user_to_wink=user.id)
LEFT JOIN messages ON (messages.id_user_from_message=user.id OR messages.id_user_to_message=user.id)
WHERE user.id!=?
AND (wink.id_user_from_wink=? OR wink.id_user_to_wink=?)
AND wink.wink_confirmed='1'
results:
[2] => Array
(
[id_wink_table] => 18
[id_user_from_wink] => 8
[id_user_to_wink] => 6
[wink_confirmed] => 1
[wink_date] => 2016-07-07 07:19:09
[id] => 8
[points] => 4
[gender] => 0
[firstname] =>
[email] => testuser1#hotmail.com
[id_messages_table] => 5
[id_user_from_message] => 6
[id_user_to_message] => 8
[message_text] => hejsan ss
[message_confirmed] => 0
[message_date] => 2016-07-09 02:43:59
)
[3] => Array
(
[id_wink_table] => 18
[id_user_from_wink] => 8
[id_user_to_wink] => 6
[wink_confirmed] => 1
[wink_date] => 2016-07-07 07:19:09
[id] => 8
[points] => 4
[gender] => 0
[firstname] =>
[email] => testuser1#hotmail.com
[id_messages_table] => 4
[id_user_from_message] => 6
[id_user_to_message] => 8
[message_text] => halluy
[message_confirmed] => 0
[message_date] => 2016-07-09 02:38:13
)
You can see that id_user_to_message and id_user_from_message are dublicate the only thing that differs is the message_text. So i want only the latest matching record from the messages table
EDIT:
SELECT wink.*,user.id,user.points,user.gender,user.firstname,user.email
FROM wink
INNER JOIN user
ON (wink.id_user_from_wink=user.id OR wink.id_user_to_wink=user.id)
**LEFT JOIN HERE returning latest message from messages table and join all rows that is returned when this left join is not used**
WHERE
user.id!=?
AND
(wink.id_user_from_wink=? OR wink.id_user_to_wink=?)
AND
wink.wink_confirmed='1'
/*
create table wink (id_wink_table int, id_user_from_wink int, id_user_to_wink int,wink_confirmed int,wink_date datetime);
insert into wink values
(18, 8,6,1,'2016-07-07 07:19:09'),(18,8,6,1,'2016-07-07 07:19:09');
create table user (id int,points int,gender int,firstaname varchar(20), email varchar(40));
truncate table user;
insert into user values
(8,4,0,null,'testuser1hotmail.com'), (8,4,0,null,'testuser1hotmail.com');
create table messages (id_messages_table int,id_user_from_message int,id_user_to_message int,message_text varchar(20),message_confirmed int,message_date datetime);
truncate table messages;
insert into messages values (5,6,8,'hejsan ss',0,'2016-07-09 02:43:59')
,(4,6,8,'halluy',0,'2016-07-09 02:38:13');
*/
select * from wink;
select * from user;
select * from messages;
SELECT wink.*,user.id,user.points,user.gender,user.firstaname,user.email, m.*
FROM wink
left outer JOIN user ON wink.id_user_from_wink = user.id OR wink.id_user_to_wink = user.id
left outer join messages m on m.id_user_from_message=user.id OR m.id_user_to_message=user.id
where m.id_messages_table =
(select max(m1.id_messages_table) from messages m1 where m.id_user_from_message=m1.id_user_from_message OR m.id_user_to_message = m1.id_user_to_message)

How to select Distinct on inner join?

Can help me, I have something problem about query select distinct, :
My table
table_pemesan
id_pms
table_pesan
no_psn
id_pms
table_dpesan
no_psn
My query mysql
select pm.id_pms,
pm.nama,
pm.date_create,
ps.no_psn,
ps.status,
dps.no_dpsn
FROM pemesan as pm
INNER JOIN pesan ps on ps.id_pms=pm.id_pms
INNER JOIN dpesan dps on dps.no_psn=ps.no_psn
ORDER BY pm.id_pms ASC
//output
Array
(
[0] => Array
(
[id_pms] => 1
[nama] => Isnan
[date_create] => 2014-05-28 23:54:54
[no_psn] => 1
[status] => sedang diproses
[no_dpsn] => 1
)
[1] => Array
(
[id_pms] => 1
[nama] => Isnan
[date_create] => 2014-05-28 23:54:54
[no_psn] => 1
[status] => sedang diproses
[no_dpsn] => 2
)
)
the array index 0 & 1 the same data, and my question how to distinct the query? thanks b4, sorry my english not good..
Try to use this query:-
SELECT DISTINCT pm.id_pms, pm.nama, pm.date_create, ps.no_psn, ps.status, dps.no_dpsn
FROM pemesan as pm
INNER JOIN pesan ps on ps.id_pms=pm.id_pms
INNER JOIN dpesan dps on dps.no_psn=ps.no_psn
ORDER BY pm.id_pms ASC

Get data from three table SQL

My MySQL tables structure (3 table)
users
id
username
images
id
user_id
image
user_follow
id
user_id
follow_id
I try to do query which give me all images from "images" table from me (user_id = 3) and my friends which I follow "user_follow" table
Now query and it give me all pictures from user I follow, I do not know what changes to add to return also my images (my user_id = 3). All users names must be in username (not id), username is in "users" table
$sql = "SELECT u.username, p.image, p.date
FROM users u, user_follow f, images p
WHERE f.user_id = 3 AND f.follow_id = u.id AND f.follow_id = p.user_id
ORDER BY p.date DESC";
it return:
[0] => Array
(
[id] => 8
[image] => fsfsf
[date] => 2012-01-24 14:58:14
)
[1] => Array
(
[id] => 7
[image] => first.jpg
[date] => 2012-01-24 14:42:27
)
[2] => Array
(
[id] => 7
[image] => second.jpg
[date] => 2012-01-24 14:42:27
)
[3] => Array
(
[id] => 6
[image] => the_last.jpg
[date] => 2012-01-24 01:49:45
)
users and their images which I follow but no my images from my user_id
SELECT
images.*,
users.username
FROM images
LEFT JOIN users ON images.user_id = users.id
LEFT JOIN user_follow ON images.user_id = user_follow.follow_id
WHERE images.user_id = 3 OR user_follow.user_id = 3
ORDER BY images.date DESC
SELECT image
FROM images
WHERE user_id = 3
OR user_id IN (
SELECT follow_id
FROM user_follow
WHERE user_id = 3
)
ORDER BY date DESC;

Categories