0

私は顧客が検索を絞り込む数値フィルターを選択できる AJAX のような検索ページを構築しています。たとえば、ユーザーが「iPhone 5」を選択し、容量 (32GB、64GB) と色 (黒、白など) のフィルターを追加したとします。

ユーザーは、カテゴリごとに 1 つのラジオ ボックスしか選択できません (つまり、32GB と黒を選択できます)。ただし、選択できませんでした (32GB と 64GB と黒のうちの 2 つが「容量」カテゴリに属しているため)。

ここで sqlfiddle にスキーマを追加しました (sqlfiddle を最小限に抑えるために、他のフィールド/データと共に削除されたばかりの適切なアプリに存在する主キーを削除したという事実を無視してください)

http://sqlfiddle.com/#!2/964425

次のことを行うためのクエリを作成するための最良の方法を誰でも提案できますか?

Get all the prices for device_id '2939' (iPhone 5) which has the 'attributes' of '32GB' AND 'Black'

私は現在これを持っていますが、これは単一の属性を選択する場合にのみ機能します:

// search for device with '64GB' & 'Black' attributes (this currently doesn't return any rows)
SELECT `prices`.*
FROM (`prices`)
LEFT JOIN `prices_attributes` ON `prices_attributes`.`price_id` = `prices`.`id`
WHERE `prices`.`device_id` =  '2939'
AND `attribute_option_id` =  '19'
AND `attribute_option_id` =  '47';

// search for device with '64GB' attribute only (this currently DOES return a row)
SELECT `prices`.*
FROM (`prices`)
LEFT JOIN `prices_attributes` ON `prices_attributes`.`price_id` = `prices`.`id`
WHERE `prices`.`device_id` =  '2939'
AND `attribute_option_id` =  '19';

データベース設計に関するアドバイスもいただければ幸いです

注: シリアル化された一致する attribute_ids を持つ「価格」テーブル内に新しい列を作成することを考えていましたが、これは最適化には適していません (たとえば、現在の方法よりも遅くなります)。

4

4 に答える 4

1

attribute_option_id に IN 演算子を使用し、値をクエリに動的に設定する必要があると思います。また、group_by を使用すると、価格ごとに 1 つの行しかないため、実質的にすべての価格を取得できます。これとは別に、デザインはOKです。

ここで、例を作成しました:

SELECT `prices`.*
FROM (`prices`)
LEFT JOIN `prices_attributes` ON `prices_attributes`.`price_id` = `prices`.`id`
WHERE `prices`.`device_id` =  '2939'
and `attribute_option_id` in ('19','47')
group by `prices`.`device_id`, `prices`.`price`;

ここで、注文句を追加して価格で注文することもできます。

order by `prices`.`price` desc;

これを解決する別の方法は、次のように個別の価格を使用することです。

select distinct(prices.price)
from prices
where prices.device_id = 2939
and id in (select price_id from prices_attributes where attribute_option_id in (19,47));
于 2013-06-25T09:36:38.940 に答える
1

devices_attributes_options テーブルに対して数回結合します。項目に必要な属性ごとに 1 回です。

このようなもの:-

SELECT *
FROM devices a
INNER JOIN prices b ON a.id = b.device_id
INNER JOIN prices_attributes c ON b.id = c.price_id
INNER JOIN devices_attributes_options d ON c.attribute_option_id = d.id AND d.attribute_value = '32GB'
INNER JOIN devices_attributes_options e ON c.attribute_option_id = e.id AND e.attribute_value = 'Black'
WHERE a.id = 2939

シリアル化された詳細をフィールドに入れることに関しては、これは本当に悪い考えであり、将来あなたを噛むことになるでしょう!

于 2013-06-25T09:41:14.273 に答える
0
SELECT * FROM prices WHERE device_id=2939 AND id IN (SELECT price_id FROM prices_attributes WHERE attribute_option_id IN (19,47));

それはあなたが探しているものですか?

EDIT:申し訳ありませんが、結合を使用してクエリを求めていることに気づきませんでした

于 2013-06-25T09:33:56.977 に答える