How can I use order by and group by in sql? - php

Here is my problem:
I have these tables:
felado fogado fehide fohide datum olvasott tartalom
felado = sender, fogado = receiver,
I would like to get all where felado or fogado is me and group the lines. So If there are the next lines
sender 1 receiver 2 id 1
sender 1 receiver 2 id 2
sender 1 receiver 2 id 3
sender 2 receiver 1 id 4
I only would like to get one from these lines, the last by ID.
Now I'm trying like this:
SELECT *
FROM belso_levelezes
WHERE (felado="'.$_SESSION["userData"]["id"].'"
or fogado="'.$_SESSION["userData"]["id"].'" )
ORDER BY id DESC
GROUP BY felado, fogado
It gaves me only one from all, but not the last records. How can I get the last records from each group?
I want to get only this:
sender 2 receiver 1 id 4

You could use a subquery to create two columns that are unique per conversation. You can then group on those columns, and grab the maximum id for the conversation. The example assumes your user id is 42:
SELECT sr1
, sr2
, max(id)
FROM (
SELECT case when Sender < Receiver then Sender else Receiver end as sr1
, case when Sender > Receiver then Sender else Receiver end as sr2
, id
FROM YourTable
WHERE 42 in (Sender, Receiver)
) as SubQueryAlias
GROUP BY
sr1
, sr2

'SELECT MAX(id),felado,fegado,... FROM belso_levelezes WHERE (felado="'.$_SESSION["userData"]["id"].'" or fogado="'.$_SESSION["userData"]["id"].'" ) GROUP BY felado, fogado '

Related

MYSQL count() -> Return the LAST ID from Number of user using the same mail

I have a table named "users". users(id,name,email). My table structure is as follows :
ID is primary key auto increment
I would like to return the email, count and the last_id of user that has the same email address
TABLE :
In other words, my query should return
last_id: 3 - count: 2 - email: jones#jones.com
last_id: 7 - count: 3 - email: silva#gmail.com
I know a piece of the query that returns the count, and the email that is repeated, but I can't get the last id.
SELECT email,count(email) FROM users GROUP BY email HAVING COUNT(email) > 1 ORDER BY count(email) DESC
Add MAX(). Also, for COUNT(email) you can define an alias and use it on HAVING & ORDER BY:
SELECT email, count(email) AS cnt_email , MAX(id) AS latest_id
FROM users GROUP BY email
HAVING cnt_email > 1
ORDER BY cnt_email DESC;
Here's a demo

Mysql select only unique rows (that appears only one time)

Consider following data in table ->
1 example#hotmail.com
2 example12#hotmail.com
3 example#hotmail.com
4 example#hotmail.com
I want it to return only the following:
2 example12#hotmail.com
...and skip the duplicate values.
The query you want is
SELECT id, email, whatEverColumn
FROM table
WHERE email IN (SELECT email
FROM table
GROUP BY email
HAVING COUNT(id) = 1)
Group by email and add having count(email) = 1

Select max value for a VARCHAR column - MySQL

My table for message inbox concept email is a primary in the table. I want to get the last message which is sent by particular email.
tbl_msg:
id
email
msg
Example Data:
Id email msg
1 xyz#gmail.com This is test
2 abc#gmail.com All is well
3 xyz#gmail.com This is test2
I want to get the last appearance of each email and msg
Id email msg
2 abc#gmail.com All is well
3 xyz#gmail.com This is test2
What I tried:
SELECT cnote.`id`,cnote.`email`,cnote.`msg` FROM `tbl_msg` cnote inner join (select distinct email,id from client_com group by email) as note
on cnote.id=note.id
Guide me if I wrong
Use This query:
SELECT m1.* FROM tbl_msgs m1 LEFT JOIN tbl_msgs m2 ON (m1.email = m2.email AND m1.id < m2.id) WHERE m2.id IS NULL;
This will join with the same table and with condition m1.id < m2.id , will get the latest one.
Another option is using subquery:
SELECT * FROM tbl_msgs WHERE id IN (SELECT MAX(id) FROM tbl_msgs GROUP BY email);
To get the latest messsage for each email address in the table you do not need a JOIN, you just need to ORDER and GROUP BY:
SELECT `id`, `email`, `msg`
FROM `tbl_msg`
GROUP BY `email`
ORDER BY `id` DESC
You can use this query:
SELECT id, email, msg FROM you_table
GROUP BY email
ORDER BY id DESC
With this one you will have only 1 row per email, and you'll have the last because is ordered by id DESC.
If you are running a PDO connection (The way I know to do it, not sure if there is a MySQLi way)
$theLastIdGiven = $handlerDbConnection->lastInsertId();
Or if you want to run it through a query, and get the last result, just add ORDER BY id DESC LIMIT 0, 1 and that will order the data by id in a descending form then get the first bit of data :)
Hope this helped you!
SELECT ID, email, Msg FROM tbl_msg WHERE ID IN (
(SELECT MAX(ID) FROM tbl_msg GROUP BY email))

Messaging System with PHP/MySQL

Hi I'm trying to make a messaging system with php and mysql.
The mysql table is simple:
id
sender
receiver
text
timestamp
I'm trying to make the messaging somewhat like Facebook/Twitter so the list is in 'conversations' and the last message in the conversation is viewed.
This is what I have atm:
(SELECT * FROM messages WHERE receiver = 13 OR sender = 13 GROUP BY receiver,sender ORDER BY id ASC) ORDER BY id ASC
SELECT messages.* FROM messages, (SELECT MAX(id) as lastid FROM messages
WHERE receiver = 13 OR sender = 13
GROUP BY CONCAT(LEAST(receiver,sender),'.',GREATEST(receiver,sender))) as conversations
WHERE id = conversations.lastid
ORDER BY timestamp DESC
what you need is a unique conversation id between the chat-partners. i've simulated this with the subquery, hope this helps
Use DESC for fetch new rows, default is ASC
(SELECT * FROM messages WHERE receiver = 13 OR sender = 13 GROUP BY receiver,sender ORDER BY id DESC)
AND SET LIMIT 1 ,1 AFTER ORDER BY
I think you need to
(receiver = '{receiver id}' AND sender = '{sender id}' ) OR (receiver ='{sender id}' AND sender = '{receiver id}' )
UPDAte:
I'm not sure if it works perfect:
SELECT * FROM messages
WHERE receiver = 13
GROUP BY receiver,sender
ORDER BY timestamp DESC
LIMIT 1
UNION ALL
SELECT * FROM messages
WHERE sender = 13
GROUP BY receiver,sender
ORDER BY timestamp DESC
LIMIT 1
to reverse the order:
ORDER BY timestamp DESC

SELECT all matching two fields and grouping by those two fields with mysql

I have a messages system which doubles out as a message system and chat system, these are differentiated by a field called source.
I have the messages sections sorting and grouping properly however in the chat section it's not grouping these accordingly, please see my SQL below:
SELECT *
FROM messages
WHERE ( senderID = "1" OR receiverID = "1" )
AND source = "1"
GROUP BY receiverID, senderID
ORDER BY addedDate DESC LIMIT 10
So the result i am expecting is just one per match, i.e. one per conversation
however am getting two for some reason.
Thanks in advance
You are probably getting two answers per chat because you would have each person in both positions
ChatID Sender Receiver
1 1 2
2 2 1
3 1 2
4 2 1
So, you'll have a record grouped by
Sender / Receiver
1 2 and
2 1
I think what you are looking for is distinct people in the conversation where the above should be considered "ONE CHAT" regardless of the position they are in. To correct this, I would do something like...
select
PreQuery.*,
m2.Message,
m2.SenderID,
m2.ReceiverID
from
( SELECT
if( m.senderID < m.receiverID, m.senderID, m.receiverID ) as Person1,
if( m.senderID < m.receiverID, m.receiverID, m.senderID ) as Person2,
max( m.ID ) as LastMessageIDPerChat,
max( m.AddedDate ) as LastMessageDate
FROM
messages m
WHERE
m.Source = "1"
AND "1" IN ( SenderID, ReceiverID )
GROUP BY
Person1,
Person2
ORDER BY
m.AddedDate DESC
LIMIT 10 ) PreQuery
JOIN Messages m2
on PreQuery.LastMessageIDPerChat = m2.ID
This will ensure that whichever ID is lower will always be in the first position, and whichever person's ID is higher is always in second position to prevent false duplicates as described above.
Also note... GROUP BY is typically expecting all non-group by fields to be associated with some aggregation, otherwise, it will just grab the first instance of a record found with a qualifying condition. So, if you want to include same people in conversations on different days, you'll want to add "AddedDate" to the group by so it could have...
Person1 Person2 on 4/20
Person1 Person3 on 4/20
Person3 Person4 on 4/20
Person1 Person2 on 4/18
Person1 Person5 on 4/17
Person3 Person4 on 4/15
To get the status of who sent last, I had to wrap the query of paired people per conversation and get the last ID of that conversation. THEN, take that and re-join back to messages on that ID (if ID is actually the primary key ID of the messages table, adjust as needed). From the join, I can get the last message for the conversation AND who the sender ID and Receiver ID were for that transaction (and any other data you want from the now alias "m2" reference).
Are you sure your IDs aren't integers?
SELECT
receiverID,
senderID,
MAX(addedDate) as maxAddedDate
FROM
messages
WHERE
(
senderID = 1
OR receiverID = 1
)
AND source = 1
GROUP BY
receiverID,
senderID
ORDER BY
addedDate DESC
LIMIT 10
Check this out.
SELECT
receiverID,
senderID,
MAX(addedDate) as maxAddedDate
FROM messages
WHERE ( senderID = 1 OR receiverID = 1) AND source = 1
GROUP BY receiverID, senderID
ORDER BY addedDate DESC
You have not mentioned any aggregation for group by fields.
If your having multiple records according to any group by fields then what should happen?
you should have sum, count,...

Categories