我有一个非常复杂的查询,我需要为每个businessType选择前N个项目。有不同数量的businessTypes,因此UNION在这种情况下不会工作。如何编辑此选项以按等级排序的每个businessType选择前10项?
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;
编辑: 我尝试了建议的方法,但似乎无法正常工作。以下是我尝试过的简化方法:
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;
通过进一步测试,我得到了一个使用(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);
答案 0 :(得分:0)
关于这个主题,我已经回答了几个问题,我从中学到了很多我从article引用的内容。
通常,我尝试实现以下内容:
SELECT columns
FROM myTable m
WHERE (
SELECT COUNT(*)
FROM myTable mc
WHERE mc.columnToGroupBy = m.ColumnToGroupBy AND mc.orderColumn >= m.orderColumn
) <= numberIWantToGroup
虽然使用没有子查询的较小表更容易演示,但正如您在question中所看到的那样,在您的情况下看起来可能类似于这样:
SELECT myColumns
FROM myTableWithAllItsJoins m1
WHERE(
SELECT COUNT(*)
FROM myTableWithAllItsJoins m2
WHERE m1.businessType = m2.businessType AND m1.rank >= m2.rank
) <= 10
这将为每个businessType选择前10名。