1

我有一个继承的数据库,需要创建一个查询来生成 SKU 的所有可能变体。一个表具有“基本”SKU,另一个表具有所有 SKU 修饰符。

例子

基本 SKU:MARIN 可以修改为

马林15 马林15 马林15 马林17 马林17 马林17 马林19 马林19 马林19 马林20 马林20 马林20

基本 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
4

3 回答 3

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
于 2011-11-01T16:53:15.873 回答
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(例如,从 Size 中删除 " 并从 Color 中获取第一个字母),但这会让您走上正确的道路。

编辑——感谢您的澄清,我已经更新了 SQL。

于 2011-11-01T16:31:25.387 回答
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(尽管在这种情况下你可能想要进一步规范化表格)。
请注意,CTEOption_Count被用于将结果限制为“全长”组合 - 使用所有选项的排列,而不仅仅是其中的一些。

于 2011-11-02T16:16:52.973 回答