Mysql:获取分组的第一个x记录

时间:2016-09-23 14:05:18

标签: mysql group-by

我有一张商店的产品表。这些产品具有valid_from和valid_to日期。在我的查询中,我想只有每个商店的前x个记录当前有效,按最后一次插入desc排序。

我目前正在使用以下查询:

SELECT * FROM 
    (
        SELECT 
            s.id as shopid, ss.name as shopname, p.name as productname, p.validfrom, p.validto
        FROM 
            product p 
        JOIN 
            shop s ON p.shopid = s.id 
        WHERE 
            s.status = 'Active' AND 
            (now() BETWEEN p.validfrom and p.validto) 
        ORDER BY p.insert DESC
    ) as a 

GROUP BY 
    shopid 
ORDER BY 
    shopname asc

这显然只给了我每个商店的最新记录,但我希望有最新的2或3条记录。我怎样才能做到这一点?

奖金问题:我希望每家店都有所不同。因此,对于商店A,我想只有第一个记录,而商店B只有前两个记录。你可以假设我拥有这个数字的每个商店都有一些数据库字段,比如s.num_of_records。

类似的问题(可能重复)让我朝着正确的方向前进,但它并没有完全解决我的问题(见最新评论)

2 个答案:

答案 0 :(得分:0)

它的工作原理是根据之前的shopid给每条记录一个等级。如果shopid是相同的,我将它排名+1。否则我将其排名为1.

但是仍然存在问题。即使我使用shopid订购,但所有商店的排名都不正确。我在查询中添加了lastshopid来检查,虽然记录是按结果中的商店排序的,但lastshopid有时会有另一个id。我认为一定是因为订购是在最后而不是在开始时完成的。

任何人都知道如何解决这个问题?我需要按照正确的顺序购买这些等级解决方案。

答案 1 :(得分:0)

您可以使用product表格的附加LEFT JOIN来计算稍后插入的同一商店的商品数量。该数字可与您的num_of_records列进行比较。

SELECT s.id as shopid, s.name as shopname,
       p.name as productname, p.validfrom, p.validto

FROM shop s

JOIN product p 
  ON  p.shopid = s.id 

LEFT JOIN product p1
  ON  p1.shop_id    = p.shop_id
  AND p1.validfrom <= NOW()
  AND p1.validto   >= NOW()
  AND p1.`insert`  >  p.`insert`

WHERE s.status = 'Active'
  AND p.validfrom  <= NOW()
  AND p.validto    >= NOW()

GROUP BY p.id

HAVING COUNT(p1.id) + 1 <= s.num_of_records

ORDER BY shopname asc

可能有用的索引:shop(status, name)product(shop_id, validfrom)product(shop_id, validto)(可能是第二个)。

注1:如果您为同一商店同时插入了两个产品(同一秒),并且两个产品都是该商店限定列表中的最后一个,则会同时选择它们。如果您使用insert列中的AUTO_INCREMENT列,则不会发生这种情况。

注意2:根据组大小(每个商店的产品数量),此查询可能会很慢。