我有一张商店的产品表。这些产品具有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。
类似的问题(可能重复)让我朝着正确的方向前进,但它并没有完全解决我的问题(见最新评论)
答案 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:根据组大小(每个商店的产品数量),此查询可能会很慢。