2011-11-01 39 views
1

我有一個我已經繼承的數據庫,需要創建一個查詢來生成SKU的所有可能的變體。一個表具有「基礎」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

這不夠通用,或者你的問題缺乏清晰度。您似乎添加了'OptionValue'的第一個字符,其中'OptionName'是Color,但如果'OptionName'是Size,則添加'OptionValue'的數字部分。還有什麼其他的'選項名稱',他們如何對待? –

+0

對不起大家,格式似乎已關閉,並且「SkuModifier」列已脫離屏幕。這些值來自「SkuModifier」列。 – Bryan

+1

@Bryan - 你有(可能)超過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正被用來將結果限制爲'全長'組合 - 使用所有選項的排列,而不僅僅是其中的一部分。

+0

這個例子是特定於某個版本的SQL Server的嗎?我似乎無法讓它運行。我在SQL Server 2005.我想我需要替換所有的「||」與+。之後,我得到了有關「類型在列中的錨點和遞歸部分之間不匹配」的錯誤以及列「組合」的錯誤 – Bryan

+0

啊,對不起,這在DB2上運行得非常好。 |'在SQL中是字符串連接的普遍性,我猜不是(DB2不使用'+' - 你有'CONCAT()'函數嗎?我不知道爲什麼你得到一個類型不匹配的錯誤遞歸查詢 - CTE _應該繼承所選列的類型。也許你需要將它包裝在手動轉換爲'varchar'或其他東西? –

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(例如,刪除「從規模,並採取從顏色的第一個字母),但是這將讓你在正確的道路。

編輯 - 感謝您的澄清,我更新了SQL。

+0

看起來沒問題,但也許'base.ProductID = color.ProductID'和'size'同樣應該加入到連接條件中。你怎麼看? –

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 
相關問題