1

特定のスペックを持つ製品を探しています。仕様の複雑な組み合わせのため、別のテーブルとの an:m リレーションである別のテーブルがあります。

product
id | other data ...
---+---------------
1  | bike
2  | bus
3  | car

product_spec
product_id | spec_id
-----------+---------------
1          | 1
1          | 2
1          | 3
2          | 1
2          | 3
2          | 4
3          | 2
3          | 4

ここで、特定の仕様を持つ製品を見つける必要があります。製品に必要な仕様のリストがある場合、これはうまく機能します。

SELECT p.id FROM product p, product_spec s
WHERE p.id = s.product_id AND s.spec_id IN (1, 2, 3)
GROUP BY p.id HAVING COUNT(p.id) = 3

(3 は製品が持つ必要のある仕様の数です) 製品 1 を与えます

SELECT p.id FROM product p, product_spec s
WHERE p.id = s.product_id AND s.spec_id IN (1, 3)
GROUP BY p.id HAVING COUNT(p.id) = 2

製品 1 と 2 が得られます。ここで問題が発生します。

仕様が 1で、仕様が2 または 4製品をすべて取得したい場合はどうすればよいでしょうか。

SELECT p.id FROM product p, product_spec s
WHERE p.id = s.product_id AND
    (s.spec_id = 1 OR s.spec_id IN (2, 4))
GROUP BY p.id HAVING COUNT(p.id) = 2

(明らかに) 製品 1 と 3 を返しますが、スペック 2 と 4 の両方を持っているが 1 を持っていないため、誤って 3 を返します。

さまざまな仕様句の値 (仕様グループ 1 = 1、仕様グループ 2 = 2 (仕様グループ 3 = 4 など) など) を指定して、それらを合計して使用することHAVING SUM(extra_field) = 3を考えていましたが、そうすることに失敗しました。

では、そのようなクエリをどのように行うのでしょうか? 複数のクエリに頼る必要がありますか (そして、最善の方法は何でしょうか)?

私はMySQLを使用していますが、質問は単一のシステムに限定されていないと思います.

これらのテスト テーブルを再作成するステートメントは次のとおりです。

CREATE TABLE product (
  id int(11) unsigned NOT NULL AUTO_INCREMENT,
  title varchar(20) NOT NULL,
  PRIMARY KEY (id)
);
INSERT INTO product (id, title) VALUES (1, 'bike'), (2, 'bus'), (3, 'car');
CREATE TABLE product_spec (
  product_id int(10) unsigned NOT NULL,
  spec_id int(10) unsigned NOT NULL,
  PRIMARY KEY (product_id,spec_id)
);
INSERT INTO product_spec (product_id, spec_id) VALUES (1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 2), (3, 4);
4

1 に答える 1

1

SUM+CASE を使用して、個々の「カテゴリ」の合計を計算し、組み合わせた HAVING クエリを使用できます。

SELECT p.id 
FROM 
  product p, 
  product_spec s
WHERE p.id = s.product_id 
GROUP BY p.id 
HAVING 
  SUM(case when s.spec_id = 1 then 1 else 0 end) > 0 and 
  SUM(case when s.spec_id in (2,4) then 1 else 0 end) > 0 
于 2013-04-23T11:41:59.050 に答える