我有一个包含众多列的表格,包括类别和评级。在整个表中,有两个类别值:类别1和类别2.评级值范围从1到5.以下anayltic查询检索每个评级的4个产品,不论其类别,因此,4个评级为1的产品,4个产品与等级2等等......(id> 10)没有特别重要的意义)
SELECT
DISTINCT x.*
FROM
(SELECT t.*,
CASE WHEN @rating != t.rating THEN @rownum := 1
ELSE @rownum := @rownum + 1 END
AS rank,
@rating := t.rating
AS var_rating
FROM products t
JOIN (
SELECT @rownum := NULL, @rating := ''
) r
WHERE ( id > 10 )
ORDER BY t.rating, price
) x
WHERE
x.rank <= 4
我希望修改它以检索每个类别的每个评级的4个产品。请有人帮忙。
非常感谢
答案 0 :(得分:0)
This page在“select-n-per-group”问题上非常棒。
我基本上在我的解决方案中遵循它。
这些查询选择每个(类别,评级)最便宜的4种产品。在价格平局的情况下,它选择具有较小ID的那个。
如果您只想要4个产品(类别,评级)而不考虑价格,请跳过p.price<=products.price
行。
方法1(易于理解):
SELECT *
FROM products
where (
select count(*) from products as p
where p.category = products.category
and p.rating = products.rating
and p.price <= products.price
and p.id < products.id -- in case of tie with price
) < 4
ORDER BY category,rating,price;
内部查询说要计算有多少物品比你便宜或者价格相同,而外部查询说只挑选比你价格低于/等价物少于4件的物品。
如果您想使用用户变量,可以尝试:
SET @num := 0, @cat := '', @rating := '';
SELECT category,rating,id,price
FROM (
SELECT category,rating,id,price,
@num := if(@cat = category AND @rating=rating, @num + 1, 1) as row_number,
@cat := category as dummy,
@rating := rating as dummy2
FROM products
ORDER BY category,rating,price,id
) AS p WHERE p.row_number <= 4;
内部查询按类别,评级,价格和ID对您的表进行排序,并在每个(类别,评级)对中分配行号。外部查询从每个中选择前4个。
该页面上的最后一个方法会有这个查询,但是它不起作用,除非你的列上有某种索引(我的MySQL foo不足以解决它) :
ALTER TABLE products ADD KEY(???);
SET @num := 0, @cat := '', @rating := '';
SELECT category,rating,id,price,
@num := if(@cat = category AND @rating=rating, @num + 1, 1) as row_number,
@cat := category as dummy,
@rating := rating as dummy2
FROM products FORCE INDEX (???)
GROUP BY category,rating, ???
HAVING row_number <= 2;
据说依赖于MYSQL在ORDER BY
中执行GROUP BY
,因此确保按要求排序行。