2

製品、プロパティ、および product_properties の 3 つのテーブルがあります。テーブル構造と値のサブセットを以下に示します。

products
---------------------------------------------
|  id  |  name  |   description   |  price  |
---------------------------------------------
|   1  | Camera |  Color Camera   |   100   |
|   2  | Lens 1 |  Camera Lens 1  |   20    |
|   3  | Lens 2 |  Camera Lens 2  |   30    |
---------------------------------------------

properties
------------------------------------------
|  id |  name          |  display        |
------------------------------------------
|  1  |  lens_mount    |   Lens Mount    |
|  2  |  image_circle  |   Image Circle  |
|  3  |  focal_length  |   Focal Length  |
|  4  |  lens_family   |   Lens Family   |
------------------------------------------

product_properties
------------------------------------------------
|  id  | value    | product_id |  property_id  |
------------------------------------------------
|  1   | F-Mount  | 2          |  1            |
|  2   | C-Mount  | 3          |  1            |
|  3   | 42.01 mm | 2          |  2            |
|  4   | 13.00 mm | 3          |  2            |
|  5   | 10.00    | 2          |  3            |
|  6   | 12.00    | 3          |  3            |
|  7   | Standard | 1          |  4            |
|  8   | Standard | 2          |  4            |
|  9   | Standard | 3          |  4            |
------------------------------------------------

ここに私の出力条件があります:

lens_mount = 'F-Mount' および image_circle >= 40 mm および focus_length > 5 を持つカメラ 1 のすべてのレンズを検索します (ここでは「標準」である lens_family でカメラとレンズを一致させます)。

これについて次のクエリを試しました:

SELECT * FROM products 
  INNER JOIN product_properties ON products.id = product_properties.product_id
  INNER JOIN properties ON properties.id = product_properties.property_id 
  WHERE (product_properties.value = 'Standard') 
    AND (properties.name = 'lens_mount' AND product_properties.value = 'F-Mount') 
    AND (properties.name = 'image_circle' AND product_properties.value >= ABS('40 mm')) 
    AND (properties.name = 'focal_length' AND product_properties.value >= 5)

ただし、このクエリは、条件が 1 つしかない場合にのみ正しい結果を返します。すべての条件で、価値はありません。where 条件で AND の代わりに OR を使用してみましたが、正しい出力が得られませんでした。

誰でもこれを整理できますか。前もって感謝します。

4

3 に答える 3

0

すべての条件を OR し、各 product_id に対していくつの条件が満たされているかをカウントする必要があります。したがって、句GROUP BY product_idを使用して結果をフィルタリングします。HAVING

SELECT product_properties.product_id, count(*) as conditions_satisfied FROM products 
  INNER JOIN product_properties ON products.id = product_properties.product_id
  INNER JOIN properties ON properties.id = product_properties.property_id 
WHERE product_properties.value = 'Standard'
 OR properties.name = 'lens_mount' AND product_properties.value = 'F-Mount'
 OR properties.name = 'image_circle' AND product_properties.value >= ABS('40 mm')
 OR properties.name = 'focal_length' AND product_properties.value >= 5
GROUP BY product_properties.product_id
HAVING COUNT(*) = 4

数値の比較が本当に必要な場合、文字列であるプロパティ値を比較するのは難しい場合があることに注意してください。

于 2013-08-22T20:35:58.673 に答える
0

ああ、恐ろしい EVA スキーマ。最初にすべきことは、次の SQL に従ってデータを正規化するためのビューを作成することです。

次に、そのビューの 2 つのコピー (カメラ用とレンズ用) を使用し、それらを結合して必要なものを得ることができます。

SELECT  p.id
        ,p.name
        ,pp1.value as Lens_Mount
        ,pp2.value as Image_Circle
        ,pp3.value as Focal_Length
        ,pp4.value as Lens_Family
from    products p
left outer join
        product_properties pp1
on      pp1.product_id = p.id
and     pp1.property_id = 1 --lens Mount
left outer join
        product_properties pp2
on      pp2.product_id = p.id
and     pp2.property_id = 2 --Image Circle
left outer join
        product_properties pp3
on      pp3.product_id = p.id
and     pp3.property_id = 3 --Focal Length
left outer join
        product_properties pp4
on      pp4.product_id = p.id
and     pp4.property_id = 3 --Lens Family        
where   p.name like 'Lens%'
于 2013-08-22T20:08:27.217 に答える