Получить все возможные объединения - PullRequest
1 голос
/ 01 ноября 2011

У меня есть база данных, которую я унаследовал, и мне нужно создать запрос, который генерирует все возможные варианты SKU. В одной таблице есть «базовый» номер SKU, а в другой - все модификаторы SKU.

* ** 1003 тысяча два * Пример

База 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

Ответы [ 3 ]

3 голосов
/ 01 ноября 2011
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
0 голосов
/ 02 ноября 2011

Вы можете использовать рекурсивное решение (и действительно, это, вероятно, единственный жизнеспособный ответ). Вы бы, вероятно, сохранили обработку, если бы у вас был предопределенный порядок (потому что на данный момент единственный способ, которым я могу думать, это объединение текста).

Вот общее решение, которое должно дать вам необходимые результаты.
Обратите внимание, что это было написано и запущено в 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 используется для ограничения результатов комбинациями «полной длины» - перестановками, в которых используются все параметры, а не только некоторые из них.

0 голосов
/ 01 ноября 2011
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 (например, удалить "из размера" и взять первую букву из цвета), но это приведет вас на правильный путь.- Спасибо за разъяснения, я обновил SQL.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...