2011-06-14 62 views
2

我試圖從使用SQL Server數據庫的第三方系統中提取一些數據。 DB結構看起來是這樣的:SQL Server:通過連接行。逗號分隔字段

訂購

OrderID OrderNumber 
    1   OX101 
    2   OX102 

OrderItem的

OrderItemID OrderID OptionCodes 
    1   1  12,14,15 
    2   1  14 
    3   2  15 

選項

OptionID Description 
    12  Batteries 
    14  Gift wrap 
    15  Case 
[etc.] 

我想是每一行訂單項目包括連接字段與每個選項描述。因此,像這樣:

OrderItemID OrderNumber Options 
    1   OX101  Batteries\nGift Wrap\nCase 
    2   OX101  Gift Wrap 
    3   OX102  Case 

當然這是由一個事實,即選項是一個逗號分隔字符串字段,而不是一個適當的查找表複雜。所以我需要用逗號分割它,以便加入選項表,然後將結果連接回一個字段。

起初,我嘗試創建一個函數,用逗號分隔選項數據,並將其作爲表格返回。儘管我能夠將這個函數的結果與選項表結合起來,但是我無法將OptionCodes列傳遞給聯接中的函數,因爲它似乎只適用於聲明變量或硬編碼值。

有人能指出我正確的方向嗎?

+1

如果在所有可能的情況下你想添加一個相關的表來存儲選項代碼。逗號限制列表是數據庫設計不正確的標誌,除非它僅用於顯示,並且絕不會與另一個表相關或需要列表中的數據按單個項目進行搜索。您需要儘快在數據庫中修復不好的設計選擇。修復它們的時間越長,它們越難以修復。 – HLGEM 2011-06-14 14:49:20

+0

@HLGEM - 100%同意,因爲您可以看到這樣簡單的事情基於我在下面提供的解決方案是多麼困難。 – Yuck 2011-06-14 14:52:09

+0

@Yuck,每當我看到它,我都會從你的用戶名中得到一個笑聲。我想你在註冊時說,「哦,Yuck,我必須拿出一個用戶名。」 – HLGEM 2011-06-14 14:55:22

回答

2

我會使用分裂函數(這裏是an example)來獲取單個值並將它們保留在CTE中。然後,您可以將CTE加入名爲「Option」的表格。

SELECT * INTO #Order 
FROM (
    SELECT 1 OrderID, 'OX101' OrderNumber UNION SELECT 2, 'OX102' 
) X; 

SELECT * INTO #OrderItem 
FROM (
    SELECT 1 OrderItemID, 1 OrderID, '12,14,15' OptionCodes 
    UNION 
    SELECT 2, 1, '14' 
    UNION 
    SELECT 3, 2, '15' 
) X; 

SELECT * INTO #Option 
FROM (
    SELECT 12 OptionID, 'Batteries' Description 
    UNION 
    SELECT 14, 'Gift Wrap' 
    UNION 
    SELECT 15, 'Case' 
) X; 

WITH N AS (
    SELECT I.OrderID, I.OrderItemID, X.items OptionCode 
    FROM #OrderItem I CROSS APPLY dbo.Split(OptionCodes, ',') X 
) 
SELECT Q.OrderItemID, Q.OrderNumber, 
     CONVERT(NVarChar(1000), (
     SELECT T.Description + ',' 
     FROM N INNER JOIN #Option T ON N.OptionCode = T.OptionID 
     WHERE N.OrderItemID = Q.OrderItemID 
     FOR XML PATH('')) 
     ) Options 
FROM (
    SELECT N.OrderItemID, O.OrderNumber 
    FROM #Order O INNER JOIN N ON O.OrderID = N.OrderID 
    GROUP BY N.OrderItemID, O.OrderNumber) Q 

DROP TABLE #Order; 
DROP TABLE #OrderItem; 
DROP TABLE #Option; 
+0

...我錯過了你的問題的第二部分。有很多關於使用'COALESCE'進行字符串連接的例子 - 儘管有很多人建議不要這樣做,因爲它是一種黑客行爲。恕我直言,這感覺就像你應該在表現層做的事情,而不是一個SQL查詢。 – Yuck 2011-06-14 14:22:48

+0

謝謝,這看起來不錯。即使我自己運行該SELECT,我得到的「OptionCodes」也不是來自第一位的公認的表提示選項。 – 2011-06-14 14:40:56

+0

@蒂姆噴泉 - 我用自包含的可測試解決方案更新了這一點。 – Yuck 2011-06-14 14:45:17