I have a very complex query where I need to select the top N items per businessType. There are a variable number of businessTypes so UNION won't work in this situation. How can I edit this to select the top 10 items for each businessType ordered by rank?
SELECT data_ID,title,distance,age_rank,age_rank * 10 AS rank,age,businessType
FROM
(SELECT sd.data_ID,sd.title,p.radius,distance_scale,distance_decay,
p.distance_unit*DEGREES(ACOS(COS(RADIANS(p.latpoint))*COS(RADIANS(sd.storeLat))*
COS(RADIANS(p.longpoint - sd.storeLon))+SIN(RADIANS(p.latpoint))*
SIN(RADIANS(sd.storeLat)))) AS distance,
EXP(-POWER(GREATEST(DATEDIFF(CURDATE(),d.createDate)-scale,0),2)/
((-2*POWER(scale,2))/(2*LOG(decay)))) AS age_rank,sd.businessType,sd.store_ID,
DATEDIFF(CURDATE(),d.createDate) AS age
FROM search_data sd
LEFT JOIN data d
ON sd.data_ID = d.data_ID
JOIN (
SELECT 40.6812509 AS latpoint,-73.9809685 AS longpoint,50.0 AS radius,69.0
AS distance_unit,5 AS scale,0.5 AS decay, 1 as distance_scale, 0.001
AS distance_decay
) AS p ON 1=1
WHERE sd.storeLat
BETWEEN p.latpoint - (p.radius / p.distance_unit)
AND p.latpoint + (p.radius / p.distance_unit)
AND sd.storeLon
BETWEEN p.longpoint - (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
AND p.longpoint + (p.radius / (p.distance_unit * COS(RADIANS(p.latpoint))))
AND DATE(d.createDate) >= DATE_ADD(CURDATE(),INTERVAL -90 DAY)
) AS d
WHERE distance <= radius
AND businessType = 1
GROUP BY store_ID
ORDER BY rank DESC;
EDIT: I've tried the suggested method, but it seems to not be working. Here is what I've tried on a simplified method:
SELECT sd.title,sd.businessType
FROM search_data sd INNER JOIN (
SELECT
businessType,
GROUP_CONCAT(data_ID ORDER BY createDate DESC) grouped_deal_ID
FROM
search_deals
GROUP BY store_ID) businessType_max
ON sd.businessType = businessType_max.businessType
AND FIND_IN_SET(sd.data_ID,grouped_deal_ID) <= 10
ORDER BY sd.businessType ASC;
With further testing I was able to get a simple version working with (http://www.erikhaselhofer.com/?p=1793):
SELECT RowNum,businessType,createDate
FROM(
SELECT IF(@businessType=businessType,@ctr:=@ctr+1,@ctr:=1) as RowNum, @businessType:=businessType as businessType,title,createDate
FROM search_data
JOIN (SELECT @ctr:=1) as a
ORDER BY businessType, createDate DESC) as b
WHERE RowNum in (1,2,3) AND businessType IN (1,2,3,4,5,6,7);