2011-06-14 39 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