2017-09-23 30 views
1

我有一个包含超过60列的UPS/Fedex跟踪编号的宽表。我正在尝试减少列数并建立父母之间的关系。SQL Server - 将多个列转换为多个行

SELECT 
    [TRACKING-NO1], [TRACKING-NO2], [TRACKING-NO3], [TRACKING-NO4], 
    [TRACKING-NO5], [TRACKING-NO6], [TRACKING-NO7], [TRACKING-NO8], 
    [TRACKING-NO9], [TRACKING-NO10] 
FROM 
    [CustomerServiceOrderEntry].[dbo].[InvoicedOrdersTempTable] 
WHERE 
    [TRACKING-NO2] IS NOT NULL 

输出返回一行(60+)列中所有跟踪号码的列表。如果有儿童跟踪号码,则将填入第2-60列;如果没有儿童跟踪号码,则2 - 60将为NULL。

我想要做的是有一个家长跟踪号码和相关的孩子跟踪号码,并标志以表明它是一个孩子。

Current Structure

New Output

你可以提供任何帮助,将不胜感激......

回答

0

我们需要使用UNPIVOT的转换列排。

但是UNPIVOT不返回任何没有子列的行。

这就是为什么我们需要另外确定这种行。

SELECT 
    [TRACKING-NO1] TrackingNumberParent , 
    'TRUE' TrackingNumberChildren 
    ,TrackingNumberChild 
FROM 
    (SELECT * FROM [CustomerServiceOrderEntry].[dbo].[InvoicedOrdersTempTable]) SRC 
     UNPIVOT(TrackingNumberChild FOR COL IN (
      [TRACKING-NO2], 
      [TRACKING-NO3], 
      [TRACKING-NO4], 
      [TRACKING-NO5], 
      [TRACKING-NO6], 
      [TRACKING-NO7], 
      [TRACKING-NO8], 
      [TRACKING-NO9], 
      [TRACKING-NO10])) PVT 
UNION ALL 
SELECT 
    [TRACKING-NO1] TrackingNumberParent, 
    'FALSE' TrackingNumberChildren, 
    NULL TrackingNumberChild 
FROM 
    [CustomerServiceOrderEntry].[dbo].[InvoicedOrdersTempTable] 
WHERE 
    [TRACKING-NO2] IS NULL 
ORDER BY 
    TrackingNumberParent 
+0

谢谢!这正是我需要的!做得好! –

+0

不客气。如果答案正确,你会点击答案检查吗? –

0

下应该是相当快的,因为它只能接管基表单通...

SELECT 
    TrackingNumberParent = iot.[TRACKING-NO1], 
    TrackingNumberChildren = CASE WHEN ctn.[TRACKING-NO] IS NULL THEN 'False' ELSE 'True' END, 
    TrackingNumberChild = ctn.[TRACKING-NO] 
FROM 
    [CustomerServiceOrderEntry].[dbo].[InvoicedOrdersTempTable] iot 
    OUTER APPLY ( 
       SELECT 
        tn.COL_NO, 
        tn.[TRACKING-NO] 
       FROM (VALUES 
        (2, iot.[TRACKING-NO2]), (3, iot.[TRACKING-NO3]), (4, iot.[TRACKING-NO4]), 
        (5, iot.[TRACKING-NO5]), (6, iot.[TRACKING-NO6]), (7, iot.[TRACKING-NO7]), 
        (8, iot.[TRACKING-NO8]), (9, iot.[TRACKING-NO9]), (10, iot.[TRACKING-NO10]) 
        ) tn (COL_NO, [TRACKING-NO]) 
       WHERE 
        (
         tn.[TRACKING-NO] IS NOT NULL 
         OR 
         tn.COL_NO = 2 
        ) 
       ) ctn;