one is to many relationship, getting latest row - mysql

lead_sp_id sp_id phone
1 5 111
2 5 222
3 5 333
4 3 444
5 3 555
6 3 666
7 3 777
8 5 888
act_id lead_sp_id sp_id act_time
1 1 5 2012-12-31 14:20:49
2 1 5 2012-12-30 14:20:49
3 2 5 2012-12-29 14:20:49
4 2 5 2012-12-31 14:20:49
5 2 5 2012-12-28 14:20:49
6 4 3 2012-12-31 14:20:49
7 4 3 2012-12-28 14:20:49
8 4 3 2012-12-25 14:20:49
result I would like to get is
phone | lead_sp_id | sp_id | act_time
111 | 1 | 5 | 2012-12-31 14:20:49
222 | 2 | 5 | 2012-12-31 14:20:49
Now I know I have to use a join statement and using the regular join statement just gives me too many result including the old dates all I am looking to to do is to get the latest act_name and act_time for each phone number based on the sp_id.

Try this:
SELECT a.phone, b.lead_sp_id, b.sp_id, b.act_time
FROM leadsptable a
INNER JOIN (SELECT a.lead_sp_id, a.sp_id, a.act_time
FROM acttable a
INNER JOIN (SELECT lead_sp_id, MAX(act_time) act_time
FROM acttable GROUP BY lead_sp_id
) b ON a.lead_sp_id = b.lead_sp_id AND a.act_time = b.act_time
) b ON a.lead_sp_id = b.lead_sp_id AND a.sp_id = b.sp_id

Try this query
SELECT
*
FROM table1 as t1
INNER JOIN (
SELECT
*
FROM
table2
INNER JOIN (SELECT MAX(act_id) FROM table2 GROUP BY act_id)
as r on r.act_id = table2.act_id
) as t2 on t1.sp_id = t2.sp_id

Related

Limit up to 10 ids from table 1 and get all the records from table 2 which matches the ids of table 1

I have a table1 for example:
orderID userId orderName orderTime...
1 11
2. 12
3. 11
4. 14
5. 11
6. 13
7. 11
8. 15
9. 16
10. 11
... ...
I have another table table2:
table2ID orderID item price ....
101 1 Apple 1.99
102 1 Banana 2.99
103 1 Grapes 0.99
104 4 pizza 6.99
105 4 drink 0.99
105. 3 chicken 1.99
106. 3 apple 1.99
I have tried this :
SELECT a.*, b.* FROM `table1` a
RIGHT JOIN table2 b on a.orderID = b.orderID
WHERE a.userID = 11 order by a.`orderTime` DESC LIMIT 25;
I want to get upto 10 unique orderIDs from table 1 of user 11 and all the details of that 10 ids from table 2. If I do LIMIT 25 then I don't get all the information.
I want my output as:
orderID userId orderName orderTime... table2ID orderID item price
1 11 101 1 Apple 1.99
1 11 102 1 Banana 2.99
1 11 103 1 Grapes 0.99
3 11 105 3 chicken 1.99
3 11 106 3 apple 1.99
SELECT a.*, b.*
FROM ( SELECT *
FROM a
WHERE a.userID = 11
LIMIT 10) as a
JOIN b
ON a.orderID = b.orderID

Select record from table with not in other table

I am stuck in query I have a table like this
budget_details
id budget_id expenditure_head_id budget
1 1 1 1233
2 1 2 333
3 1 3 567
4 2 1 343
5 2 2 343
6 2 3 6767
7 2 4 557
expenditure_heads
id name
1 abc
2 xyz
3 qwe
4 uvw
I want to get all the expenditure_heads from budget_details that even
if not in budget_details like here budget_id=1 does not contain expenditure_head_id 4
but I want to select that to with 0 or null displaying
I tried this but it not displaying expenditure_head_id 4
select `expenditure_heads`.`name`, `budget_details`.`budget`, `budget_details`.`id` from
`budget_details`
right join `expenditure_heads` on `budget_details`.`expenditure_head_id` = `expenditure_heads`.`id`
where `budget_details`.`budget_id` = 1"
The where avoid you to get the missing row you need. The left join is done on the ON statement, so this query should work for you:
SELECT EH.name, BD.budget, BD.id FROM expenditure_heads EH
LEFT JOIN budget_details BD
ON (BD.expenditure_head_id = EH.id AND BD.budget_id = 1)

MySql select all rows in one table based on MAX value in another table

I want to be able to get all the data from table 1 and table 3 below but in addition to this I also want to get the latest application stage from table 2. The latest application stage is determined by getting the max stage_date for each application.
Table 1: applications
id | applicant_id | col_x | col_y | col_z
-----------------------------------------
10 300 a b c
11 310 a b c
12 320 a b c
13 330 a b c
14 340 a b c
Table 2: application_progress
id | application_id | application_stage | stage_date | stage_notes
------------------------------------------------------------------
1 10 DRAFT 2013-01-01 (NULL)
2 10 APPLICATION 2013-01-14 (NULL)
3 10 PHASE1 2013-01-30 (NULL)
4 11 DRAFT 2013-01-01 (NULL)
4 12 DRAFT 2013-01-01 (NULL)
5 13 DRAFT 2013-01-01 (NULL)
6 14 DRAFT 2013-01-01 (NULL)
7 14 APPLICATION 2013-01-14 (NULL)
EDIT: third table
Table 3: applicants
id | applicant_name | applicant_address | programme_id
------------------------------------------------------
300 Applicant 1 abc 1
310 Applicant 2 xyz 2
320 Applicant 3 xyz 2
330 Applicant 4 xyz 2
340 Applicant 5 xyz 2
Returned data set
applicant_id | applicant_name | current_stage
---------------------------------------------------------
300 Applicant 1 PHASE1
310 Applicant 2 DRAFT
320 Applicant 3 DRAFT
330 Applicant 4 DRAFT
340 Applicant 5 APPLICATION
Am struggling with this one and would appreciate any help.
PS. Tried to put an example of sqlfiddle but it's down at the minute. I'll update this with the sqlfiddle when it's back up if haven't had an answer before this.
You can do this with a correlated subquery:
select a.*,
(select application_stage
from application_progress ap
where ap.application_id = a.id
order by stage_date desc
limit 1
) MostRecentStage
from applications a;
EDIT:
You can joining in the applicant data with something like this::
select a.*, aa.*,
(select application_stage
from application_progress ap
where ap.application_id = a.id
order by stage_date desc
limit 1
) MostRecentStage
from applications a join
applicant aa
on a.applicant_id = aa.id;

Mysql left join or much simpler way?

I need to order data according to order index from other table. and order the data with the same 'id' according to entry date.
i cant figure it out how to join data and order using mysql command.
Table1
id name order
1 Ali 1
2 Cenk 3
3 Tan 2
Table 2
id tid m date
1 232 msj1 3
2 434 msj2 2
1 453 msj4 1
3 455 msj5 2
2 541 msj6 4
1 234 msj7 2
3 132 msj8 6
Needed query result
id tid m date
1 453 msj4 1
1 234 msj7 2
1 232 msj1 3
3 455 msj5 2
3 132 msj8 6
2 434 msj2 2
2 541 msj6 4
This should work:
select t2.id, t2.tid, t2.m, t2.date
from t2
left join t1 on t2.id=t1.id
order by t1.order
This orders by the ordering field from table 1.

MySQL : Get max values of groups

I have a table:
user_id | fav_song_genre | votes_as_fav_member
--------+----------------+--------------------
1 | hip hop | 3
2 | hip hop | 5
3 | rock | 8
4 | rock | 6
How do I get only results of user_id's with the highest votes_as_fav_member per group fav_song_genre:
Something like
SELECT *, MAX(votes_as_fav_member) as most_votes
FROM table
GROUP BY
fav_song_genre
I'm using that but it's not giving me the ID's of the members with most votes per genre.
This is not a problem of MySQL, rather a bit of logic problem with your approach.
Let's say we have the following:
user_id | fav_song_genre | votes_as_fav_member
--------+----------------+--------------------
1 | hip hop | 3
2 | hip hop | 5
3 | rock | 8
4 | rock | 6
5 | hip hop | 5
6 | rock | 8
Which ID should the query return? Should it return only one? or all that have the same amount of votes?
So, if you require only a single ID, what is the differentiation of a draw?
Lieven beat me to the SQL resolution by a few seconds, though.
Reasoning goes like
SELECT max vote for each genre
JOIN back with the original table to retrieve the additional columns for the records found.
SQL Statement
SELECT us.*
FROM UserSongs us
INNER JOIN (
SELECT fav_song_genre
, MAX(votes_as_fav_member) AS votes_as_fav_member
FROM UserSongs
GROUP BY
fav_song_genre
) usm ON usm.fav_song_genre = us.fav_song_genre
AND usm.votes_as_fav_member = us.votes_as_fav_member
Edit
How can I make sure the person with the lower ID is returned
SELECT MIN(us.user_id) as user_id
, us.fav_song_genre
, us.votes_as_fav_member
FROM UserSongs us
INNER JOIN (
SELECT fav_song_genre
, MAX(votes_as_fav_member) AS votes_as_fav_member
FROM UserSongs
GROUP BY
fav_song_genre
) usm ON usm.fav_song_genre = us.fav_song_genre
AND usm.votes_as_fav_member = us.votes_as_fav_member
GROUP BY
us.fav_song_genre
, votes_as_fav_member
Not sure if that's what you are asking:
SELECT g.fav_song_genre
, t.user_id
, g.most_votes
FROM yourTable t
JOIN
( SELECT fav_song_genre
, MAX(votes_as_fav_member) as most_votes
FROM yourTable
GROUP BY fav_song_genre
) AS g
ON t.fav_song_genre = g.fav_song_genre
AND t.votes_as_fav_member= g.most_votes
;
I created the table and tested, and I think this will also work
Table Data:
user_id fav_song_genre votes_as_fav_member
1 hip_hop 3
2 hip_hop 5
3 rock 8
4 rock 6
5 blues 20
6 indie 18
7 rock 35
8 country 33
9 hip_hop 35
10 indie 5
11 blues 7
12 hip_hop 59
13 indie 187
14 classic 45
15 country 61
16 hip_hop 243
Query:
select t.user_id, t.fav_song_genre, t.votes_as_fav_member
from (
select user_id, max(votes_as_fav_member) as max_votes, fav_song_genre
from table1 group by fav_song_genre
)
as x inner join table1 as t on t.votes_as_fav_member = x.max_votes and t.fav_song_genre = x.fav_song_genre;
Results:
user_id fav_song_genre votes_as_fav_member
5 blues 20
7 rock 35
13 indie 187
14 classic 45
15 country 61
16 hip_hop 243