あなたはこれを行うことができます:
Products
:
ProductId
主キー、
ProductName
、
- ...
Materials
:
MaterialID
主キー、
MaterialName
.
Units
:
ProductsSizesOptions
:
SizeOptionId
主キー、
Height
、
Width
、
UnitId
REFERENCES Units(UnitId)
製品ごとに異なるタイプのユニットを処理するための外部キー制約。
ProductsMaterialOptions
:
MaterialOptionId
、
Quantity
、
MaterialId
REFERENCES Materials(MaterialId)
各製品のオファーのさまざまなタイプのマテリアルを処理するための外部キー制約。
ProductsOffers
:
OfferId
主キー、
ProductId
外部キー制約REFERENCES Products(ProductId)
、
MaterialOptionId
外部キー制約 REFERENCES ProductsMaterialOptions(MaterialOptionId)`,
SizeOptionId
外部キー制約REFERENCES ProductsSizesOptions(SizeOptionId)
、
Price
.

たとえば、質問に投稿したサンプル データの場合、次JOIN
の表を使用して、各製品のこれらのオファーを簡単に取得できます。
SELECT
po.OfferId,
p.ProductNAme,
mo.Quantity,
m.MaterialName,
so.Height,
so.width,
u.UnitName,
po.Price
FROM products AS p
INNER JOIN ProductsOffers AS po ON p.ProductId = po.ProductId
INNER JOIN ProductsMaterialOptions AS mo ON po.MaterialOptionId = mo.MaterialOptionId
INNER JOIN ProductsSizesOptions AS so ON so.SizeOptionId = po.SizeOptionId
INNER JOIN Units AS u ON u.UnitId = so.unitId
INNER JOIN Materials AS m ON m.MaterialId = m.MaterialId;
これにより、次のような結果が得られます。
| OFFERID | PRODUCTNAME | QUANTITY | MATERIALNAME | HEIGHT | WIDTH | UNITNAME | PRICE |
-----------------------------------------------------------------------------------------
| 1 | Business Card | 100 | Card Stock | 4 | 3 | gsm | 500 |
| 2 | Business Card | 200 | Card Stock | 4 | 3 | gsm | 800 |
次に、フロントエンド アプリケーションから、これらの結果を希望どおりにフォーマットできます。
アップデート
Products
:
ProductId
、
ProductName
、
- ...
Options
:
可能なオプションを保存するには:
OptionId OptionName
1 Material
2 Shape
and so on
Properties
:
PropertyId
、
PropertyName
、
PropertyTypeId
.
PropertiesTypes
:
PropertyTypeId
、
PropertyTypeName
.
このテーブルは必要ないかもしれませんが、アプリケーションでこのフィールドを表示する方法を知るために、フロント エンド アプリケーションから使用できます。たとえば、次の値が含まれる場合があります。
1 Integer
2 String
3 Decimal
...
OptionsProperties
:
OptionPropertyId
、
OptionId
、
PropertyId
.
Shape
および などの各オプションのプロパティMaterial
:
OptionPropertyId OptionId PropertyId
1 1 1
2 2 2
3 2 3
4 2 4
ProductOptions
:
ProductOptionId
、
ProductId
、
OptionId
.
ProductOptionsValues
:
ProductOfferOptionsId
、
ProductId
、
PropertyId
、
NumericValue
、
TXTValue
.
ProductsOffers
:
OfferId
、
ProductOfferOptionsId
、
Quantity
、
Price
.

次のように、各製品のオファーのリストを取得できます。
SELECT
p.ProductName,
MAX(CASE WHEN pr.PropertyName = 'Material Name' THEN PropertyValue END) AS 'Material Name',
MAX(CASE WHEN pr.PropertyName = 'Height' THEN PropertyValue END) AS 'Height',
MAX(CASE WHEN pr.PropertyName = 'Width' THEN PropertyValue END) AS 'Width',
MAX(CASE WHEN pr.PropertyName = 'Unit' THEN PropertyValue END) AS 'Unit',
o.Quantity,
o.Price
FROM products AS p
INNER JOIN
(
SELECT
ProductId,
PropertyId,
ProductOfferOptionsId,
COALESCE(NumericValue, TXTValue) AS PropertyValue
FROM
ProductOptionsValues
) AS ov ON ov.ProductId = p.ProductId
INNER JOIN OptionsProperties AS op ON op.PropertyId = ov.PropertyId
INNER JOIN Properties AS pr ON op.PropertyId = pr.PropertyId
INNER JOIN ProductsOffers AS o ON o.ProductOfferOptionsId = ov.ProductOfferOptionsId
GROUP BY p.ProductName,
o.Quantity,
o.Price;
これにより、次のことが得られます。
| PRODUCTNAME | MATERIAL NAME | HEIGHT | WIDTH | UNIT | QUANTITY | PRICE |
-----------------------------------------------------------------------------
| Business Card | gsm Card Stock | 3.5 | 2.5 | inch | 100 | 500 |
| Business Card | gsm Card Stock | 3.5 | 2.5 | inch | 200 | 800 |
もちろん、このクエリは意味がありません。すべてのプロパティのリストを取得するには、動的 SQL を使用してこれを動的に行う必要があります。次のコードをストアド プロシージャに入れることができます。
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT CONCAT('MAX(IF(pr.PropertyName = ''',
pr.PropertyName, ''', ov.PropertyValue, 0)) AS ', '''', pr.PropertyName , '''')
) INTO @sql
FROM Properties AS pr
INNER JOIN
(
SELECT
PropertyId,
COALESCE(NumericValue, TXTValue) AS PropertyValue
FROM
ProductOptionsValues
) AS ov ON pr.PropertyId = ov.PropertyId;
SET @sql = CONCAT('SELECT
p.ProductName, ', @sql , ', o.Quantity,
o.Price
FROM products AS p
INNER JOIN
(
SELECT
ProductId,
PropertyId,
ProductOfferOptionsId,
COALESCE(NumericValue, TXTValue) AS PropertyValue
FROM
ProductOptionsValues
) AS ov ON ov.ProductId = p.ProductId
INNER JOIN OptionsProperties AS op ON op.PropertyId = ov.PropertyId
INNER JOIN Properties AS pr ON op.PropertyId = pr.PropertyId
INNER JOIN ProductsOffers AS o ON o.ProductOfferOptionsId = ov.ProductOfferOptionsId
GROUP BY p.ProductName,
o.Quantity,
o.Price');
prepare stmt
FROM @sql;
execute stmt;
これにより、すべてのプロパティが動的にピボットされます。