我有一个我已经继承的数据库,需要创建一个生成SKU所有可能变体的查询。一张桌子有" base" SKU和其他表格包含所有SKU修饰符。
实施例
基础SKU:MARIN可以修改为
MARINR15 MARINB15 MARING15 MARINR17 MARINB17 MARING17 MARINR19 MARINB19 MARING19 MARINR20 MARINB20 MARING20
基础SKU
ProductID SKU
----------- ---------------
532 MARIN
SKU修饰符
ProductID OptionName OptionValue SkuModifier
----------- -------------------- ------------------------ -----------
532 Color Red R
532 Color Green G
532 Color Blue B
532 Size 17" 17
532 Size 15" 15
532 Size 19" 19
532 Size 20" 20
答案 0 :(得分:3)
DROP TABLE #Base
DROP TABLE #Modifiers
CREATE TABLE #Base
(
ProductId int,
SKU varchar(32)
)
CREATE TABLE #Modifiers
(
ProductId int,
OptionName varchar(32),
OptionValue varchar(32),
SKUModifier varchar(32)
)
INSERT INTO #Base
SELECT 532, 'MARIN'
INSERT INTO #Modifiers
SELECT 532, 'Color', 'Red', 'R' UNION ALL
SELECT 532, 'Color', 'Green', 'G' UNION ALL
SELECT 532, 'Color', 'Blue', 'B' UNION ALL
SELECT 532, 'Size', '17"', '17' UNION ALL
SELECT 532, 'Size', '15"', '15' UNION ALL
SELECT 532, 'Size', '19"', '19' UNION ALL
SELECT 532, 'Size', '20"', '20'
SELECT B.SKU + M.SKUModifier + M2.SKUModifier FROM #Base B
JOIN #Modifiers M ON B.ProductId = M.ProductId AND M.OptionName = 'Color'
JOIN #Modifiers M2 ON B.ProductId = M2.ProductId AND M2.OptionName = 'Size'
结果:
MARINR17
MARING17
MARINB17
MARINR15
MARING15
MARINB15
MARINR19
MARING19
MARINB19
MARINR20
MARING20
MARINB20
答案 1 :(得分:0)
SELECT
base.sku+color.SkuModifier+size.SkuModifier
FROM base
INNER JOIN modifiers as color ON color.OptionName = 'Color'
INNER JOIN modifiers as size ON size.OptionName = 'Size'
您可能必须处理OptionValue(例如,删除“从大小和从Color中取出第一个字母”,但这将使您走上正确的道路。
编辑 - 感谢您的澄清,我已经更新了SQL。
答案 2 :(得分:0)
您可以使用递归解决方案(事实上,这可能是唯一可行的答案)。如果你有一个预定义的排序,你可能会保存处理(因为目前我认为这样做的唯一方法是文本连接)。
这是一个通用的解决方案,可以为您提供所需的结果 请注意,这是在DB2(iSeries)上编写和运行的 - 您可能需要为SQL Server调整它。
WITH Combined(productId, options, combination, level) as (
SELECT productId, optionName, skuModifier, 1
FROM #Modifiers
UNION ALL
SELECT a.productId, a.options || b.optionName,
a.combination || b.skuModifier, a.level + 1
FROM Combined as a
JOIN #Modifiers as b
ON b.productId = a.productId
AND a.options not like ('%' || b.optionName || '%')),
Option_Count(productId, count) as (SELECT productId, COUNT(DISTINCT optionName)
FROM #Modifiers
GROUP BY productId)
SELECT a.sku || COALESCE(b.combination, '')
FROM #Base as a
LEFT JOIN (Combined as b
JOIN Option_Count as c
ON c.productId = b.productId
AND c.count = b.level)
ON b.productId = a.productId)
哪个收益率:
MARIN17R
MARIN15R
MARIN19R
MARIN20R
MARIN17G
MARIN15G
MARIN19G
MARIN20G
MARIN17B
MARIN15B
MARIN19B
MARIN20B
MARINR17
MARING17
MARINB17
MARINR15
MARING15
MARINB15
MARINR19
MARING19
MARINB19
MARINR20
MARING20
MARINB20
就个人而言,我认为我会尝试建立一些排序 - 这至少会让你淘汰处理optionName
(尽管在这种情况下你可能想要进一步规范化表格)。
请注意,CTE Option_Count
用于将结果限制为“全长”组合 - 使用所有选项的排列,而不仅仅是其中一些选项。