2012-09-14 203 views
1

我試圖從類別ID(1,5,12),從MySQL數據庫中cat_order + prod_order排序類別內選擇不同的產品MySQL的SELECT,JOIN,GROUP BY查詢優化

問題:

如果產品在多於1個類別中發現的我需要顯示所述第一結果,

即:產品號1被分配給類別1和5,我需要沿從第1類顯示產品數1與其prod_order並跳過列表中的類別5,

  • 本質上,我需要顯示類別1中的所有產品,然後轉到類別5並顯示所有產品,其中產品ID以前未顯示,然後轉到列表中的其他類別(12)

如果我運行類似:

SELECT 
    prod_to_cat.prod_id AS prod_to_cat_prod_id, 
    prod_to_cat.prod_order AS prod_to_cat_prod_order, 
    prod_to_cat.cat_id AS prod_to_cat_cat_id, 
    prod_to_cat.cat_order AS prod_to_cat_cat_order, 
    products.id, 
    products.name 

FROM 
    prod_to_cat, products 

WHERE 
    prod_to_cat.prod_id = products.id 
AND prod_to_cat.cat_id IN (1, 5, 12) 
GROUP BY 
    prod_to_cat.prod_id 
ORDER BY 
    prod_to_cat_cat_order ASC, 
    prod_to_cat_prod_order DESC 

我得到不一致的結果(產品1將不會從該列表中的第一個類別可以選擇),這就是爲什麼我選擇不「GROUP選擇由PROD_ID 「然後用另一個選擇將其與prod_id中的組相比較。

像這樣:

SELECT 
    prod_to_cat_prod_id, 
    prod_to_cat_prod_order, 
    prod_to_cat_cat_id, 
    name 
FROM 
    (
     SELECT 
      prod_to_cat.prod_id AS prod_to_cat_prod_id, 
      prod_to_cat.prod_order AS prod_to_cat_prod_order, 
      prod_to_cat.cat_id AS prod_to_cat_cat_id, 
      prod_to_cat.cat_order AS prod_to_cat_cat_order, 
      products.id, 
      products.name 
     FROM 
      prod_to_cat, products 
     WHERE 
      prod_to_cat.prod_id = products.id 
     AND prod_to_cat.cat_id IN (1, 5, 12) 
     ORDER BY 
      prod_to_cat_cat_order ASC, 
      prod_to_cat_prod_order DESC 
    ) AS prod 
GROUP BY 
    prod_to_cat_prod_id 
ORDER BY 
    prod_to_cat_cat_order ASC, 
    prod_to_cat_prod_order DESC 
LIMIT 0, 10; 

我所試圖做的事:

我試圖找到一個更efficiant的方式來做到這一點。

表結構:

prod_to_cat: 

prod_id | cat_id | cat_order | prod_order | 
    1  1   1   2 
    2  1   1   0 
    3  1   1   0 
    1  5   2   4 
    4  5   2   0 


products: 


id | name | descr | price | 
1 name_1 
2 name_2 
3 name_3 
4 name_4 

每個產品可以在任何數量的類別,例如產品ID 1是在上面的例子中的類別ID 1和5。

非常感謝您的回覆。 帕夏

+0

。 。您意識到您的查詢由一個字段(prod_id)分組幷包含其他列。這是使用稱爲隱藏列的MySQL功能。其餘列來自該組內的任意記錄。特別是,prod_order在給定數據的情況下具有未指定的值。隱藏列專爲所有值相同的情況而設計。 –

回答

3

你想要的groupwise minimum

SELECT prod_to_cat.*, 
     products.name 
FROM  prod_to_cat NATURAL JOIN (
      SELECT prod_id, 
        MIN(cat_id) AS cat_id 
      FROM  prod_to_cat 
      WHERE cat_id IN (1, 5, 12) 
      GROUP BY prod_id 
     ) t 
    JOIN products ON t.prod_id = products.id 
ORDER BY prod_to_cat.cat_order ASC, 
     prod_to_cat.prod_order DESC 

見它sqlfiddle

+0

+1爲「groupwise minimum」。 –

+0

eggyal,非常感謝您的回覆, - 選擇MIN(cat_id)將不起作用,因爲類別列表未被排序 - 例如,類別列表可以是: 5,1,12 在這種情況下我需要從5中選擇所有產品,然後選擇1從1中選擇所有產品,但不包括顯示在5中的產品,而不是移動到12等... 無論如何, - 非常感謝你的回覆! - 任何其他建議? – pasha

+1

@pasha:在這種情況下,用'ELT(MIN(FIELD(cat_id,1,5,12)),1,5,12)'替換MIN(cat_id)'。請參閱[sqlfiddle](http://sqlfiddle.com/#!2/a3696/3/0)。 – eggyal