2012-09-16 73 views
2

我有一個帶屬性系統的產品目錄。使用多個IN子查詢改進SQL查詢(按屬性系統過濾)

我想創建一個系統,允許客戶端通過屬性瀏覽產品(如在Magento上)。因此,我試圖以編程方式檢索具有特定值(或具有許多特定值的許多屬性)屬性的產品列表(通過ID返回)。

它運行良好,但我的SQL查詢是可怕的!

對於爲例:如果我想要檢索的有這3個屬性(和值)的產品清單,這是我當前的SQL查詢:

  • 1過濾器:id_attribut = 3,值=「Lorem存有「
  • 第二濾波器:id_attribut = 4和值= '的Test2'
  • 第三濾波器:id_attribut = 2,值= 'BAR2'

    SELECT products.id 
    FROM products 
    JOIN products_attributs ON products_attributs.id_product = products.id 
    WHERE products_attributs.value = 'Lorem ipsum' 
    AND products_attributs.id_attribut = 3 
    AND products_attributs.id_product   ==> return ID: 25, 27 
    IN (
        SELECT id_product 
        FROM products_attributs 
        WHERE id_attribut = 4 
        AND value = 'Test2'     ==> return ID: 27 
        AND id_product IN (
         SELECT id_product 
         FROM products_attributs 
         WHERE id_attribut = 2 
         AND value = 'Bar2'   ==> return ID: 27 
        ) 
    )

結果:返回ID 27(這是與客戶選擇的三個屬性相對應的唯一產品)。

它工作的很好,但它並不優雅,也不是非常優化(想象一下,如果我有超過10個過濾器!)。

的products_attributs表:

------------------------------------------------- 
| id | id_product | id_attribut | value   | 
------------------------------------------------- 
| 1 | 25   | 1   | Foo   | 
| 2 | 25   | 2   | Bar   | 
| 3 | 25   | 3   | Lorem ipsum | 
| 4 | 25   | 4   | Test   | 
| 5 | 27   | 1   | Foo2   | 
| 6 | 27   | 2   | Bar2   | 
| 7 | 27   | 3   | Lorem ipsum | 
| 8 | 27   | 4   | Test2   | 
| 9 | 28   | 1   | ... etc  | 
-------------------------------------------------

我怎麼能提高呢?

非常感謝!

回答

1

「好」SQL的唯一方法是爲所有屬性創建列。這很難保持,所以我不會推薦它。

鑑於比,你可以多次,參加回你的屬性表是這樣的:

SELECT p.id 
FROM products p 
LEFT OUTER JOIN products_attributs pa1 ON pa1.id_product = p.id and pa1.value = 'Lorem ipsum' AND pa1.id_attribut = 3 
LEFT OUTER JOIN products_attributs pa2 ON pa2.id_product = p.id and pa2.value = 'Test2' AND pa1.id_attribut = 4 
LEFT OUTER JOIN products_attributs pa3 ON pa3.id_product = p.id and pa3.value = 'Bar2' AND pa1.id_attribut = 2 

好運。

+0

它不適用於「LEFT OUTER JOIN」語句,但可以使用「JOIN」。 非常感謝您的回答:您的SQL查詢非常完美! – Guicara

+0

如果您只是使用JOIN,它將需要所有三個屬性的行。如果你描述它「不起作用」,也許有人可以提供幫助。 –