2017-09-23 83 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;