Reputation: 186552
There are 3 tables in question - properties, specials, and properties_specials.
I want n results back where n is the number of properties, and the corresponding special is the one with the MAX(specials.startdate).
I first tried doing this after aggregation but the MIN/MAX doesn't seem to affect the result set at all:
SELECT
p.id,
s.*,
MAX( s.startdate )
FROM
properties p
LEFT JOIN properties_specials ps ON ps.properties_id = p.id
LEFT JOIN specials s ON s.id = ps.specials_id
GROUP BY p.id
Using a subquery with max doesn't work because it just grabs the total max:
SELECT
p.id,
s.*
FROM
properties p
LEFT JOIN properties_specials ps ON ps.properties_id = p.id
LEFT JOIN (
SELECT id, MAX( specials.startdate )
FROM specials
) AS s ON s.id = ps.specials_id
GROUP BY p.id
And finally doing an ORDER BY in the subquery doesn't seem to work either because even though I specify ORDER BY specials.startdate DESC
or ORDER BY specials.startdate ASC
, the result is the same for:
properties table
id name
----------------
11 Hotel
properties_specials table
properties_id specials_id
----------------
11 33
11 34
specials table
id startdate
----------------
33 2016-01-02
34 2016-01-10
How can I adjust this properly so I get the most recent / max after the join to properties_specials?
EDIT: Came up with a sqlfiddle for this. I think the differing factor may have been that the same special can be applied to different properties in the mapping table - if that's the case sorry for not specifying earlier.
Upvotes: 1
Views: 102
Reputation: 1269563
You can do this by using an aggregation to get the maxdate per property and then joining these back in:
select p.*, s.*
from properties p join
(select ps.properties_id, max(s.startdate) as maxsd
from properties_specials ps join
specials s
on s.id = ps.specials_id
group by ps.properties_id
) maxps
on p.id = maxps.properties_id join
properties_specials ps
on ps.properties_id = p.id join
specials s
on ps.specials_id = s.id and s.startdate = maxps.maxsd;
EDIT:
Note the above query had an error. It was missing an on
clause, which resulted in many duplicates (and would have been an error in any database other than MySQL).
Another approach is to just use the id instead of the date. Plugging directly into the above query:
select p.*, s.*
from properties p join
(select ps.properties_id, max(s.id) as maxid
from properties_specials ps join
specials s
on s.id = ps.specials_id
group by ps.properties_id
) maxps
on p.id = maxps.properties_id join
properties_specials ps
on ps.properties_id = maxps.properties_id join
specials s
on s.id = maxps.maxid;
Upvotes: 1
Reputation: 2278
Here is the quick answer:
SELECT ps.properties_id, max(s.startdate)
FROM specials s, properties_specials ps
WHERE s.id = ps.specials_id
GROUP BY 1
If you want all the information, try the following:
SELECT p.id pid, p.name, s.id sid, s.startdate
FROM properties p, specials s, properties_specials ps, (
SELECT ps.properties_id pid, max(s.startdate) maxdate
FROM specials s, properties_specials ps
WHERE s.id = ps.specials_id
GROUP BY 1
) as pmax
WHERE p.id = ps.properties_id AND s.id = ps.specials_id
AND p.id = pmax.pid AND pmax.maxdate = s.startdate
Upvotes: 1