MySQL: select last row of each pair - php

I have a little problem to solve, but I can't. I have the following chat table:
id user friend msg date
----------------------------------------------------------------------
1 1 2 Hello Bob! 2014-07-04 01:00
2 1 2 How are you doing? 2014-07-04 01:01
3 2 1 I'm fine bro! 2014-07-04 02:30
4 1 3 Hey Mark :D 2014-07-04 02:31
5 3 1 Yo! 2014-07-04 02:32
6 4 1 Wassup?! 2014-07-04 07:00
I'm working on a PHP getInbox($uid) method that returns an array of the last message of each pair (user and friend). I tried a SELECT query with GROUP BY friend, but it is incomplete.
SELECT * FROM `chat`
GROUP BY `friend`
WHERE `user` = $uid OR `friend` = $uid
The desired result is:
id user friend msg date
----------------------------------------------------------------------
3 2 1 I'm fine bro! 2014-07-04 02:30
5 3 1 Yo! 2014-07-04 02:32
6 4 1 Wassup?! 2014-07-04 07:00
I would appreciate a help!

SELECT c.* FROM
chat c
JOIN
(SELECT
max(id) max_id,
(CASE WHEN user < friend THEN user ELSE friend END) user_a,
(CASE WHEN user < friend THEN friend ELSE user END) user_b
FROM chat
GROUP BY user_a, user_b) t1 ON t1.max_id = c.id
The case statements select (user,friend) in ascending order. For example, both (1,2) and (2,1) will be converted to (1,2). An ordered pair uniquely identifies a conversation. Finally, the latest id is selected for each ordered pair and rows having those ids are displayed from the chat table.

Related

fetch data with two table like blow image

Hi i have a two tables and i want to fetch data, one table have agent_id and 2nd table has agent_id, and agent_sale record so, i just want to show data with join query so that i can get not repeat user_id with multiple sales record according to sales.
1st table - agent_sales_daily
id agent_id agent_username userlevel status date
1 2 rajesh 2 1 2019-09-04
2 3 ram 2 1 2019-09-04
4 4 amit 2 1 2019-09-04
2st table - agent_sale
id agent_id agent_sale status date
1 2 300 1 2019-09-04
2 3 500 1 2019-09-04
3 3 200 1 2019-09-04
4 4 0 1 2019-09-04
5 3 600.55 1 2019-09-05
7 3 300.50 1 2019-09-05
i am trying like this
SELECT b.agent_username,a.agent_sale,b.agent_id,a.date
FROM agent_sale a
left join agent_sales_daily b ON a.agent_id = b.agent_id
$sqlQ ="SELECT b.agent_username,a.agent_sale,b.agent_id,a.date
FROM $sale a
left join $table b ON a.agent_id = b.agent_id
$res = $conn->query($sqlQ);
i want output put is like 1 agent_username have multiple sales and i want show record like ram has 3 sales and show one ram and three sales record but not duplicate ram
thanks in advance

MYSQLi select how to

Im trying to select every lasted insert row with a match_id and show all match_id's on a php page, but not show multiple rows on same match_id.
Since it is a logging page for my kids football games i will insert multiple rows on same match_id to mark if he scores, so i wont be updating same match_id.
Here you can see a example how the database looks. I have some more columns also but just to get you the idea how it looks.
(AI)id match_id team1 team2 result1 result2 goal timenow
1 1 US ENG 0 0 0 00:00
2 1 US ENG 1 0 0 08:00
3 1 US ENG 1 1 0 13:00
4 1 US ENG 2 1 1 20:00
5 2 US FRA 0 0 0 00:00
6 2 US FRA 1 0 1 04:00
7 2 US FRA 1 1 0 26:00
8 3 US GER 0 0 0 00:00
9 3 US GER 1 0 0 16:00
The result i would like to get is a php page that lists just the last row of every unique match id.
Example html/php would show lika below:
US-ENG 2-1
US-FRA 1-1
US-GER 1-0
Hope you understands what i mean :)
EDIT: got it working by this line of code if somebody other have the same needs.
Thanks to Akilan who lead me in right direction :)
SELECT * FROM table WHERE id IN (SELECT MAX( id ) FROM table GROUP BY match_id) ORDER BY `table`.`timenow` DESC
You can do a order by with time and group by your match id can achieve the desired output right??
For example,
SELECT * FROM match_table GROUP BY match_id ORDER BY TIME(timenow)
Happy Coding,
AK
This will help you
select group_concat(team1,'-',team2,' ',result1,'-',result2) from match_table group by match_id order by match_id DESC LIMIT 1;
SELECT group_concat(t1.team1,'-',t1.team2,' ',t1.result1,'-',t1.result2) from table t1
LEFT JOIN table t2
ON (t1.matchid = t2.matchid AND t1.id < t2.id)
WHERE t2.id IS NULL;

Remove Duplicate Row Except The Last One

I have this table on MySql:
Table1
ID CODE USER NUMBER ADJUSTMENT ADJUST_DATE
1 abc Frank 10245 1 2015/04/20
2 def Jonathan 25410 0 2015/04/21
3 ghi Karen 55214 3 2015/05/05
4 abc Frank 10245 2 2015/04/21
5 abc Frank 10245 4 2015/04/22
I would like to remove the duplicated data and leave the last entry by date:
ID CODE USER NUMBER ADJUSTMENT ADJUS_DATE
2 def Jonathan 25410 0 2015/04/21
3 ghi Karen 55214 3 2015/05/05
5 abc Frank 10245 4 2015/04/22
CODE, USER, NUMBER, ADJUSTMENT, ADJUS_DATE are 'Unique'
I need to create a temporary table with the result because I need all the records.
Generate a subset of the max date grouped by like values in columns and join back to the base set...
SELECT A.ID, A.Code, A.user, A.Number, A.Adjustment, A.Adjust_date
FROM table1 A
INNER JOIN (SELECT Code, User, Number, max(adjust_date) mDate
FROM table1 group by Code, User, Number) B
on A.code = B.code
and A.user = B.User
and A.Number = B.Number
and A.Adjust_date = B.mdate

Select Multiple Values SQL

I have a table where the data are as follow
ID Classroom Person
1 1 Alfred
2 1 Maria
3 2 Maria
4 2 Zoe
5 2 Alfred
6 3 Nick
7 3 Paul
8 3 Mike
9 3 Alfred
10 4 Zoe
11 4 Maria
I want to select and return only the Classroom that has as Person only 'Alfred' and 'Maria'
Following statement :
Select * from table_name where (Person='maria') and (Person=Alfred')
doesn't seem to work.
You can see a SQL Fiddle here,
You can use group by and having:
select classroom
from table t
group by classroom
having count(*) = 2 and
sum(person in ('maria', 'Alfred')) = 2;
This assumes that one person cannot be in a classroom multiple times.
This checks that there are two names in the classroom and they are for the two names of interest. If you can have duplicates, you would want:
having count(distinct name) = 2 and
count(distinct case when person in ('maria', 'Alfred') then person end) = 2;
Try this. Group by and having with Count should work.
SELECT Classroom
FROM tablename
WHERE Person IN( 'maria', 'Alfred' )
GROUP BY classroom
HAVING Count(Person) = 2

I want the last row of all players in a specific month+year

Here is a simplified version of my sql table of 2 months (ORDERED BY DATE):
player_id |
date |
score
1 2011-05-25
1200
2 2011-05-25
3400
3 2011-05-26
3200
4 2011-05-26
4400
1 2011-05-28
1000
2 2011-05-28
2000
3 2011-05-29
3000
4 2011-05-29
4000
1 2011-06-24
1300
2 2011-06-24
2500
3 2011-06-24
5000
4 2011-06-24
3000
Basically, I want a query that shows the last score of all players in a specific month/specific year.
Example:
If I want the final scores of all players in the month 05, te result
would be:
1 2011-05-28 1000
2 2011-05-28 2000
3 2011-05-29 3000
4 2011-05-29 4000
My sql query so far:
SELECT m1.* FROM table m1
LEFT JOIN table m2 ON (m1.player_id = m2.player_id AND m1.date < m2.date)
WHERE m2.date IS NULL
AND month(m1.date) = 05
AND year(m1.date) = 2011
ORDER BY score DESC);
This doesn't seem to show all players, only players that didn't play in the months after 05. Where do I add the date select?
**EDIT
John Nestoriak's answer bellow did the trick for me :)
I think he's referring to the technique shown here: Retrieving the last record in each group
With the additional constraint of he doesn't want the last record but the last record in a given month.
Oddly enough you have to give that additional constraint twice, once in the join condition and again to filter the results. This should do it for you.
SELECT m1.* FROM table m1
LEFT JOIN table m2 ON
(m1.player_id = m2.player_id AND m1.date < m2.date
AND m2.date < '2011-06-01')
WHERE m2.date IS NULL AND month(m1.date) = 5 AND year(m1.date) = 2011
Assuming that the (player_id, date) combination in Unique:
SELECT
t.*
FROM
TableX AS t
JOIN
( SELECT
player_id
, MAX(date) AS maxDate
FROM
TableX
WHERE
date BETWEEN '2011-05-01'
AND LAST_DAY('2011-05-01')
GROUP BY
player_id
) AS tg
ON
(tg.player_id, tg.maxDate) = (t.player_id, t.date)
ORDER BY
t.score DESC

Categories