あなたはこれを行うことができます:
Products:
ProductId主キー、
ProductName、
- ...
Materials:
MaterialID主キー、
MaterialName.
Units:
ProductsSizesOptions:
SizeOptionId主キー、
Height、
Width、
UnitIdREFERENCES Units(UnitId)製品ごとに異なるタイプのユニットを処理するための外部キー制約。
ProductsMaterialOptions:
MaterialOptionId、
Quantity、
MaterialIdREFERENCES 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;
これにより、すべてのプロパティが動的にピボットされます。