2015-09-26 52 views
2

我正在嘗試解除數據傳輸,但得到了一些奇怪的結果。我怎樣才能做到這一點?如何在SQL Server中UNPIVOT表?

下面是我的代碼和結果的截圖。 (SQL Fiddle

select distinct recId, caseNumber, servtype, mins 
from 
(
    select 
     recid 
     ,caseNumber 
     ,[preEnrollment_type] 
     ,[preEnrollment_minutes] 
     ,[screening_type] 
     ,[screeningEnA_minutes] 
     ,[ifsp_type] 
     ,[ifsp_minutes] 
    from 
     CaseManagementProgressNote 
    where 
     [formComplete]=1 
     and [reviewed]<>1 
     and [dataentry]<>1 
     and [caseManagementEntry]=1 
     and [serviceCoordinator] <> '[email protected]' 
     and [contactDateTime] >= '1/1/2015' 
     and [childID] is not null 
) as cp 
unpivot 
(
    servType for servTypes in ([preEnrollment_type],[screening_type],[ifsp_type]) 
) as up1 
unpivot 
(
    mins for minutess in ([preEnrollment_minutes],[screeningEnA_minutes],[ifsp_minutes]) 
) as up2 
order by 
    recId 

頂部分是奇怪unpivot ED數據和底部部分是實際的表。

enter image description here

正如你可以在unpivot ED數據看出,[column]_type重複兩次,並有不正確的對應值。

我需要

1439 964699 -NA- null 
1439 964699 SC  45 
1439 964699 TCM FF 20 

採取也考慮到我還有更多的列選擇。

這是我用mssqltips

的例子的SQL Fiddle高於參考。

+0

如果您添加了SQL小提琴,那麼您很有可能會得到有用的答案。 –

+0

添加了SQL小提琴:) – esausilva

回答

1

你似乎有一個印象,你的兩個UNPIVOT操作以某種方式鏈接。他們不是,除了第一個UNPIVOT執行第一個的結果。

如果你看看你的第UNPIVOT結果:

select * 
from 
(
    select 
     recid 
     ,caseNumber 
     ,[preEnrollment_type] 
     ,[preEnrollment_minutes] 
     ,[screening_type] 
     ,[screeningEnA_minutes] 
     ,[ifsp_type] 
     ,[ifsp_minutes] 
    from 
     CaseManagementProgressNote 
) as cp 
unpivot 
(
    servType for servTypes in ([preEnrollment_type],[screening_type],[ifsp_type]) 
) as up1 

你會看到

╔═════════╦═════════════╦════════════════════════╦═══════════════════════╦═══════════════╦═══════════╦════════════════════╗ 
║ recid ║ caseNumber ║ preEnrollment_minutes ║ screeningEnA_minutes ║ ifsp_minutes ║ servType ║  servTypes  ║ 
╠═════════╬═════════════╬════════════════════════╬═══════════════════════╬═══════════════╬═══════════╬════════════════════╣ 
║ 143039 ║  964699 ║ (null)     ║     45 ║   20 ║ -NA-  ║ preEnrollment_type ║ 
║ 143039 ║  964699 ║ (null)     ║     45 ║   20 ║ SC  ║ screening_type  ║ 
║ 143039 ║  964699 ║ (null)     ║     45 ║   20 ║ TCM FF ║ ifsp_type   ║ 
╚═════════╩═════════════╩════════════════════════╩═══════════════════════╩═══════════════╩═══════════╩════════════════════╝

應該從這個明確的第二UNPIVOT操作做了什麼,爲什麼它給你結果它確實:從此得到你想要的結果,你不需要需要unpivot。 UNPIVOT將列轉換爲行。這不是你想要的。你已經有了你想要的行。您需要的是將所有三個minutes列合併到一個列中,具體取決於servTypes。有辦法做到這一點,例如通過增加一個表達你的SELECT列表,像這樣:

CASE servType 
WHEN 'preEnrollment_type' THEN preEnrollment_minutes 
WHEN 'screening_type' THEN screeningEnA_minutes 
WHEN 'ifsp_type' THEN isfp_minutes 
END 

或者使用@ ander2ed的做法並刪除UNPIVOT完全,如果你不介意它不過濾出NULL s。

鏈接到蓋這個問題太文章:

唯一複雜這裏輸出的手機匹配到相應的手機類型 - 對於這一點,我們需要做一些字符串審訊,以確保電話1到匹配PhoneType1,Phone2匹配PhoneType2等。

它通過執行第二個UNPIVOT來解決問題,然後過濾結果。您可以通過鏈接servTypesminutess使其工作。在您的特定樣本數據中,它們的第一個字符足以用於識別,並且在兩列中相同,因此您可以將where left(servTypes, 1) = left(minutess, 1)添加到您的查詢中。

這對我來說似乎毫無意義,我也不會推薦它,但它是文章和查詢之間的區別,這是您的查詢在文章不起作用時不起作用的原因。

+0

我添加了'case'語句,它工作的很棒!! ...並且感謝你的解釋 – esausilva

0

您可以在此處使用Cross Apply來代替unpivot。我發現語法更容易理解,並且您將能夠保留空值。嘗試這樣的:

select recid, casenumber, servtype, mins 
from CaseManagementProgressNote a 
cross apply (VALUES (preEnrollment_type, preEnrollment_minutes), 
        (screening_type, screeningEna_Minutes), 
        (ifsp_type, ifsp_minutes)) unpvt (servtype, mins) 
+0

我喜歡這個查詢中的語法,但它不能在SQL Server中運行。它確實在SQL Fiddle中運行。 SQL Server給我以下錯誤'關鍵字'VALUES'附近的語法不正確.' – esausilva

+0

有趣。你使用的是什麼版本的SQL?它在Microsoft SQL Server 2008 R2中適用於我。 – ander2ed

+0

SQL Server Studio 2012在我的電腦中,但實際的數據庫是在SQL Server 2005 – esausilva