2011-04-12 85 views
3

MYSQL - select first 4 records for each category in a table非常相似,但沒有一個可接受的答案,並且一個答案沒有太大意義,所以我再次提問。從MySQL中的每個類別中選擇2種產品

我有一個PRODUCTS表3列:IDNAMECATEGORY 現在,我想知道的是,如果它是在所有可能的選擇2個產品爲每個不同的類別,而不在PHP循環做什麼的查詢。

所選產品的順序並不重要,它們也可能是隨機的。但重要的是,我只有每個類別最多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

你的結果應該如何?把它放在你的代碼中以更好地理解 – Omid 2011-04-12 10:50:15

回答

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

這工作很好。只要確保在運行查詢之前設置變量即可。否則它將無法工作。 SET @ prev = 0,@ rownum = 0; – 2011-12-05 23:08:13

1

這應該做你在找什麼。

SET @I=0; 
SET @C=''; 
SELECT ID, Name, Category FROM (
    SELECT B.*, 
    IF(@C != B.Category, @I:=1, @I:[email protected]+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 
+0

謝謝,這似乎工作,但我似乎無法得到我的頭在RowNum var ...當我選擇它與ID,名稱和類別列它有時還包含3而HAVING條款規定它不應該高於2? – ChrisR 2011-04-12 11:50:40

+0

這真的很奇怪 - 我只是試了一下,注意到它適用於<= 2並且給出了rownums 1和3,但是正確的2條記錄,但是如果你用<= 3做它,它不再起作用 - 它只給每個類別2個記錄,仍然是rownums 1和3.嘗試用選擇的值 - 我無法弄清楚這種關係。 您是否嘗試過我的解決方案? – Simon 2011-04-12 12:10:35

+0

@ Simon143:是的,你的解決方案實際上給了我正確的rowNumbers ...謝謝! – ChrisR 2011-04-12 12:23:26

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) 

查詢挑選分鐘,每個類別的最高,並返回兩者(或者只有一個,如果它是一樣的)。

你說「所選產品的順序不重要,它們可能是隨機的」,所以這種方法應該沒問題。

相關問題