2017-09-05 39 views
-1

我想從單行生成多行並且能夠使用下面的SQL來完成它。但是我想知道是否有更好的方式來編寫這個SQL,因爲它很長,並且不適用於實時場景。謝謝。使用SQL將單行分割爲多行使用SQL

注意: - 我的查詢將返回所需的輸出,但它不是一個有效的方法 來解決問題。我的實際輸入有更多列,我不想寫'n'沒有。的SQL查詢併爲它們做一個UNION ALL。 請建議更好的解決方案。謝謝。

Input :- 
A.Col2 A.Col4 A.Col6 B.Col1 B.Col2 B.Col3 B.Col4 B.Col5 B.Col6 B.Col7 
    300 301 302 100 9011 100 9002 100 9002 100 
    300 301 302 101 8101  95 2001 100 2001 100 
    300 301 302 102 8101 105 2001 110 2001 110 

Desired output :- 
100 300 9011 100 
101 300 8101 95 
102 300 8101 105 
100 301 9002 100 
101 301 2001 100 
102 301 2001 110 
100 302 9002 100 
101 302 2001 100 
102 302 2001 110 

在我的例子中,我已經建立了總共10場的測試數據(前三個字段,其餘七個字段。)對於第四列的每一個值我要建三行四列,三列會看起來像:

(4th column, 1st column, 5th column, 6th column), 
(4th column, 2nd column, 7th column, 8th column), 
(4th column, 3rd column, 9th column, 10th column) 

我現在的SQL:

SELECT B.Col1 AS Constructioncode, 
     A.Col2 AS OccupancyCode,  
     B.Col2 AS MappingID, 
     B.Col3 AS DamageFactor 
    FROM 
( 
SELECT 0 AS Col1,300 AS Col2,0 AS Col3,301 AS Col4,0 AS Col5,302 AS Col6, 0 AS Col7 
UNION ALL 
SELECT 100 AS Col1,9011 AS Col2,100 AS Col3,9002 AS Col4,100 AS Col5,9002 AS Col6,100 AS Col7 
UNION ALL 
SELECT 101 AS Col1,8101 AS Col2,95 AS Col3,2001 AS Col4,100 AS Col5,2001 AS Col6,100 AS Col7 
UNION ALL 
SELECT 102 AS Col1,8101 AS Col2,105 AS Col3,2001 AS Col4,110 AS Col5,2001 AS Col6,110 AS Col7 
) A 
CROSS JOIN 
(
SELECT 0 AS Col1,300 AS Col2,0 AS Col3,301 AS Col4,0 AS Col5,302 AS Col6, 0 AS Col7 
UNION ALL 
SELECT 100 AS Col1,9011 AS Col2,100 AS Col3,9002 AS Col4,100 AS Col5,9002 AS Col6,100 AS Col7 
UNION ALL 
SELECT 101 AS Col1,8101 AS Col2,95 AS Col3,2001 AS Col4,100 AS Col5,2001 AS Col6,100 AS Col7 
UNION ALL 
SELECT 102 AS Col1,8101 AS Col2,105 AS Col3,2001 AS Col4,110 AS Col5,2001 AS Col6,110 AS Col7 
) B 
WHERE B.Col1 > A.Col1 
AND A.Col1 = 0 
UNION ALL 
SELECT B.Col1 AS Constructioncode, 
     A.Col4 AS OccupancyCode,  
     B.Col4 AS MappingID, 
     B.Col5 AS DamageFactor 
    FROM 
( 
SELECT 0 AS Col1,300 AS Col2,0 AS Col3,301 AS Col4,0 AS Col5,302 AS Col6, 0 AS Col7 
UNION ALL 
SELECT 100 AS Col1,9011 AS Col2,100 AS Col3,9002 AS Col4,100 AS Col5,9002 AS Col6,100 AS Col7 
UNION ALL 
SELECT 101 AS Col1,8101 AS Col2,95 AS Col3,2001 AS Col4,100 AS Col5,2001 AS Col6,100 AS Col7 
UNION ALL 
SELECT 102 AS Col1,8101 AS Col2,105 AS Col3,2001 AS Col4,110 AS Col5,2001 AS Col6,110 AS Col7 
) A 
CROSS JOIN 
(
SELECT 0 AS Col1,300 AS Col2,0 AS Col3,301 AS Col4,0 AS Col5,302 AS Col6, 0 AS Col7 
UNION ALL 
SELECT 100 AS Col1,9011 AS Col2,100 AS Col3,9002 AS Col4,100 AS Col5,9002 AS Col6,100 AS Col7 
UNION ALL 
SELECT 101 AS Col1,8101 AS Col2,95 AS Col3,2001 AS Col4,100 AS Col5,2001 AS Col6,100 AS Col7 
UNION ALL 
SELECT 102 AS Col1,8101 AS Col2,105 AS Col3,2001 AS Col4,110 AS Col5,2001 AS Col6,110 AS Col7 
) B 
WHERE B.Col1 > A.Col1 
AND A.Col1 = 0 
UNION ALL 
SELECT B.Col1 AS Constructioncode, 
     A.Col6 AS OccupancyCode,  
     B.Col6 AS MappingID, 
     B.Col7 AS DamageFactor 
    FROM 
( 
SELECT 0 AS Col1,300 AS Col2,0 AS Col3,301 AS Col4,0 AS Col5,302 AS Col6, 0 AS Col7 
UNION ALL 
SELECT 100 AS Col1,9011 AS Col2,100 AS Col3,9002 AS Col4,100 AS Col5,9002 AS Col6,100 AS Col7 
UNION ALL 
SELECT 101 AS Col1,8101 AS Col2,95 AS Col3,2001 AS Col4,100 AS Col5,2001 AS Col6,100 AS Col7 
UNION ALL 
SELECT 102 AS Col1,8101 AS Col2,105 AS Col3,2001 AS Col4,110 AS Col5,2001 AS Col6,110 AS Col7 
) A 
CROSS JOIN 
(
SELECT 0 AS Col1,300 AS Col2,0 AS Col3,301 AS Col4,0 AS Col5,302 AS Col6, 0 AS Col7 
UNION ALL 
SELECT 100 AS Col1,9011 AS Col2,100 AS Col3,9002 AS Col4,100 AS Col5,9002 AS Col6,100 AS Col7 
UNION ALL 
SELECT 101 AS Col1,8101 AS Col2,95 AS Col3,2001 AS Col4,100 AS Col5,2001 AS Col6,100 AS Col7 
UNION ALL 
SELECT 102 AS Col1,8101 AS Col2,105 AS Col3,2001 AS Col4,110 AS Col5,2001 AS Col6,110 AS Col7 
) B 
WHERE B.Col1 > A.Col1 
AND A.Col1 = 0 
+0

在你的榜樣,你硬編碼的值的查詢,所以很難以確定此unpivot的數據的邏輯。你如何得到10個3列的4列? – scsimon

+0

你檢查了本文中引用的Pivot()SQL調用https://stackoverflow.com/a/15931734/1620112 –

+0

我的輸入有10列...對於A.Col2我需要B.Col1,B.Col2, B.Col3 ... for A.Col4 I need B.Col1,B.Col4,B.Col5 ... for A.Col6 I need B.Col1,B.Col6,B.Col7。 – Teja

回答

4

下應該做的伎倆。我只用一遍就可以完成數據。

IF OBJECT_ID('tempdb..#TestData', 'U') IS NOT NULL 
DROP TABLE #TestData; 

CREATE TABLE #TestData (
    A_Col2 INT, 
    A_Col4 INT, 
    A_Col6 INT, 
    B_Col1 INT, 
    B_Col2 INT, 
    B_Col3 INT, 
    B_Col4 INT, 
    B_Col5 INT, 
    B_Col6 INT, 
    B_Col7 INT 
    ); 
INSERT #TestData (A_Col2, A_Col4, A_Col6, B_Col1, B_Col2, B_Col3, B_Col4, B_Col5, B_Col6, B_Col7) VALUES 
    (300, 301, 302, 100, 9011, 100, 9002, 100, 9002, 100), 
    (300, 301, 302, 101, 8101, 95, 2001, 100, 2001, 100), 
    (300, 301, 302, 102, 8101, 105, 2001, 110, 2001, 110); 

--==================================================================== 

SELECT 
    Constructioncode = td.B_Col1, 
    ab.OccupancyCode, 
    ab.MappingID, 
    ab.DamageFactor 
FROM 
    #TestData td 
    CROSS APPLY (VALUES 
         (td.A_Col2, td.B_Col2, td.B_Col3), 
         (td.A_Col4, td.B_Col4, td.B_Col5), 
         (td.A_Col6, td.B_Col6, td.B_Col7) 
        ) ab (OccupancyCode, MappingID, DamageFactor) 
ORDER BY 
    ab.OccupancyCode, 
    td.B_Col1; 

結果...

Constructioncode OccupancyCode MappingID DamageFactor 
---------------- ------------- ----------- ------------ 
100    300   9011  100 
101    300   8101  95 
102    300   8101  105 
100    301   9002  100 
101    301   2001  100 
102    301   2001  110 
100    302   9002  100 
101    302   2001  100 
102    302   2001  110