与MYSQL - select first 4 records for each category in a table非常相似,但没有一个可接受的答案,那里的答案没有多大意义,所以我再问一次。
我有一个包含3列的PRODUCTS
表:ID
,NAME
和CATEGORY
我现在想知道的是,如果没有在PHP循环中进行查询,就可以为每个不同的类别选择2个产品。
所选产品的顺序并不重要,它们也可能是随机的。但重要的是我每个类别最多只能有2个产品。
所以一个好的结果集将是
ID ; NAME ; CATEGORY
:::::::::::::::::::::::
152 ; APPLE ; FRUIT
185 ; ORANGE ; FRUIT
145 ; BEEF ; MEAT
141 ; PORK ; MEAT
410 ; PEPSI ; DRINKS
585 ; CARROT ; VEGETABLES
585 ; TOMATO ; VEGETABLES
答案 0 :(得分:3)
沿着这些方向的东西将起作用:
SELECT id, name, category
FROM (
SELECT *,
IF( @prev <> category,
@rownum := 1,
@rownum := @rownum+1
) AS rank,
@prev := category,
@rownum
FROM (
SELECT * FROM products
ORDER BY category, rand()
) random_prodcts
) products_ranked
WHERE rank <= 2;
它在类别中随机命令它们,然后将它们拉出来跟踪每个类别中的数量。
不确定它的扩展程度有多好。
编辑:尝试了几千条记录,似乎没问题。
答案 1 :(得分:1)
这应该可以满足您的需求。
SET @I=0;
SET @C='';
SELECT ID, Name, Category FROM (
SELECT B.*,
IF(@C != B.Category, @I:=1, @I:=@I+1) AS RowNum,
@C:=B.Category
FROM (
SELECT ID, Name, Category FROM Products GROUP BY Name, Category ORDER BY Category
) AS B HAVING RowNum <= 2
) AS A
答案 2 :(得分:1)
完整的SQL:
SELECT t.id, t.name, t.category
FROM the_table AS t
, (SELECT MIN(id) AS id_min FROM the_table GROUP BY category) AS t1
, (SELECT MAX(id) AS id_max FROM the_table GROUP BY category) AS t2
WHERE (t.id=t1.id_min) OR (t.id=t2.id_max)
查询选择每个类别的最小值和最大值并返回它们(如果相同则只返回一个)。
你说“所选产品的顺序并不重要,它们也可能是随机的”,所以这种方法应该没问题。