私のシステムには次の(たとえば簡略化された)テーブルがあります。
その目的は、機能を特定のカテゴリに指定してから、サブカテゴリまたは製品レベルでオーバーライドできるようにすることです。
さまざまな属性を持つさまざまなタイプの機能があり、それらのタイプは、機能と1:1の関係を持つ「拡張」テーブルによって表されます。
たとえば、次のようにしましょう。
- すべてのコンピューターとライトにはACアダプターがあります(カテゴリー)
- すべてのコンピューターにCPUが搭載されています(カテゴリー)
- すべてのラップトップとタブレットにはバッテリーがあります(サブカテゴリ)
- すべてのMacBookProにはHDMIポートがあります(製品)
- すべてのMacBookProおよびiPadにはRetinaディスプレイが搭載されています(製品)
これは次のようにモデル化されます。
カテゴリ:
- feature_container:id:1
- カテゴリ:id:1、名前:"コンピュータ"
- feature_container:id:2
- カテゴリ:id:2、名前:"ライト"
サブカテゴリ:
- feature_container:id:3
- サブカテゴリ:id:3、category_id:1、名前:"デスクトップ"
- feature_container:id:4
- サブカテゴリ:id:4、category_id:1、名前:"ラップトップ"
- feature_container:id:5
サブカテゴリ:id:5、category_id:1、name: "Tablet"
feature_container:id:6
- サブカテゴリ:id:6 category_id:2、名前: "Floor Light"
- feature_container:id:7
- サブカテゴリ:id:7、category_id:2、名前:"電気スタンド"
製品:
- feature_container:id:7
- 製品:id:7、subcategory_id:4、名前: "Apple MacBookAir"
- feature_container:id:8
- 製品:id:8、subcategory_id:4、名前: "Apple MacBook Pro"
- feature_container:id:9
- 製品:id:9、subcategory_id:5、名前: "Apple iPad"
カテゴリに適用される機能:
- 機能:id:1、feature_container_id:1
has_ac_adapter_feature:id:1、model_number: "ABC"
機能:id:2、feature_container_id:2
has_ac_adapter_feature:id:2、model_number: "DEF"
機能:id:3、feature_container_id:1
- has_cpu_feature:id:3、model_number: "123"
サブカテゴリに適用される機能:
- 機能:id:4、feature_container_id:4
- has_battery_feature:id:4、battery_type:"リチウムイオン"
- 機能:id:5、feature_container_id:5
- has_battery_feature:id:5、battery_type:"リチウムイオン"
製品に適用される機能:
- 機能:id:6、feature_container_id:8
- has_retina_display_feature:id:6
- 機能:id:7、feature_container_id:9
- has_retina_display_feature:id:7
- 機能:id:8、feature_container_id:8
- has_hdmi_port_feature:id:8
Light階層のデータをわざわざ挿入することはしませんが、あなたはその考えを理解します。私が持っていることを覚えておいてください:
- 何百万もの製品
- 何千ものサブカテゴリ
- 何百ものカテゴリ
- 主にサブカテゴリで定義されている数千の機能ですが、製品やカテゴリで定義されているものもあります。
- 通常はカテゴリレベル(ACアダプタ)で定義される機能が、実際には製品レベルでのみ定義される可能性があることは言うまでもありません。これはビジネス上の呼びかけであり、柔軟性と保守性によって推進されます。つまり、どの機能もどのレベルでも割り当てることができると想定する必要があります。
次のことを問い合わせたい:
CPUとACアダプターを備え、(RetinaディスプレイまたはHDMIポート)を備えたすべての製品を教えてください
私は得る必要があります:
- Apple MacBook Pro
- Apple iPad
これが私が試したことです...
私はこのようなものから始めました:
http://sqlfiddle.com/#!4/2f6cd/4/0
これは継承の問題に対処しようとしますが、これでフィルタリングを開始すると(製品にこの機能とその機能がある場合)、どの製品に複数の機能や機能があるかを簡単に見つけることができないことにすぐに気付きました(または?)。
それから私はこのようなことを始めました:
SELECT prd.id AS prd_id,
CASE
WHEN prd_lvl.ac_ftr = 1
OR cat_lvl.ac_ftr = 1
OR scat_lvl.ac_ftr = 1
THEN
1
ELSE
0
END
AS ac_ftr
FROM product prd
LEFT JOIN (SELECT prd.id AS prd_id,
prd.name AS prd_name,
NVL2 (ac_ftr.id, 1, 0) AS ac_ftr,
NVL2 (cpu_ftr.id, 1, 0) AS cpu_ftr,
NVL2 (bat_ftr.id, 1, 0) AS bat_ftr,
NVL2 (hdmi_ftr.id, 1, 0) AS hdmi_ftr,
NVL2 (ret_ftr.id, 1, 0) AS ret_ftr
FROM feature_container fc
INNER JOIN product prd
ON fc.id = prd.id
INNER JOIN feature ftr
ON fc.id = ftr.feature_container_id
LEFT JOIN has_ac_adapter_feature ac_ftr
ON ftr.id = ac_ftr.id
LEFT JOIN has_cpu_feature cpu_ftr
ON ftr.id = cpu_ftr.id
LEFT JOIN has_battery_feature bat_ftr
ON ftr.id = bat_ftr.id
LEFT JOIN has_hdmi_port_feature hdmi_ftr
ON ftr.id = hdmi_ftr.id
LEFT JOIN has_retina_display_feature ret_ftr
ON ftr.id = ret_ftr.id) prd_lvl
ON prd.id = prd_lvl.prd_id
LEFT JOIN ( --All Products and subcategory-level-features assigned
SELECT prd.id AS prd_id,
prd.name AS prd_name,
NVL2 (ac_ftr.id, 1, 0) AS ac_ftr,
NVL2 (cpu_ftr.id, 1, 0) AS cpu_ftr,
NVL2 (bat_ftr.id, 1, 0) AS bat_ftr,
NVL2 (hdmi_ftr.id, 1, 0) AS hdmi_ftr,
NVL2 (ret_ftr.id, 1, 0) AS ret_ftr
FROM feature_container fc
INNER JOIN subcategory scat
ON fc.id = scat.id
INNER JOIN feature ftr
ON fc.id = ftr.feature_container_id
INNER JOIN product prd
ON scat.id = prd.subcategory_id
LEFT JOIN has_ac_adapter_feature ac_ftr
ON ftr.id = ac_ftr.id
LEFT JOIN has_cpu_feature cpu_ftr
ON ftr.id = cpu_ftr.id
LEFT JOIN has_battery_feature bat_ftr
ON ftr.id = bat_ftr.id
LEFT JOIN has_hdmi_port_feature hdmi_ftr
ON ftr.id = hdmi_ftr.id
LEFT JOIN has_retina_display_feature ret_ftr
ON ftr.id = ret_ftr.id) scat_lvl
ON prd.id = scat_lvl.prd_id
LEFT JOIN ( --All Products and category-level-features assigned
SELECT prd.id AS prd_id,
prd.name AS prd_name,
NVL2 (ac_ftr.id, 1, 0) AS ac_ftr,
NVL2 (cpu_ftr.id, 1, 0) AS cpu_ftr,
NVL2 (bat_ftr.id, 1, 0) AS bat_ftr,
NVL2 (hdmi_ftr.id, 1, 0) AS hdmi_ftr,
NVL2 (ret_ftr.id, 1, 0) AS ret_ftr
FROM feature_container fc
INNER JOIN category cat
ON fc.id = cat.id
INNER JOIN feature ftr
ON fc.id = ftr.feature_container_id
INNER JOIN subcategory scat
ON cat.id = scat.category_id
INNER JOIN product prd
ON scat.id = prd.subcategory_id
LEFT JOIN has_ac_adapter_feature ac_ftr
ON ftr.id = ac_ftr.id
LEFT JOIN has_cpu_feature cpu_ftr
ON ftr.id = cpu_ftr.id
LEFT JOIN has_battery_feature bat_ftr
ON ftr.id = bat_ftr.id
LEFT JOIN has_hdmi_port_feature hdmi_ftr
ON ftr.id = hdmi_ftr.id
LEFT JOIN has_retina_display_feature ret_ftr
ON ftr.id = ret_ftr.id) cat_lvl
ON prd.id = cat_lvl.prd_id order by prd_id
しかし、それは同じ問題を抱えています:私は同じ行に物を置くことができません。この問題を解決する方法について何かアドバイスはありますか?
ありがとう!