2017-06-20 57 views
0

我是一名SQL初學者,並且有一個問題。我有用戶數據的表像這樣SQL Server從表中獲取行並顯示在列中

uid nid val 
+---+---+---+ 
| 1 | x | 3 | 
+---+---+---+ 
| 2 | x | 3 | 
+---+---+---+ 
| 3 | x | 3 | 
+---+---+---+ 
| 1 | y | 4 | 
+---+---+---+ 
| 2 | y | 4 | 
+---+---+---+ 
| 3 | y | 4 | 
+---+---+---+ 
| 1 | z | 5 | 
+---+---+---+ 

其中uid是用戶ID,NID是用於標識值的名稱ID val是實際值。

我想編寫一個查詢其給出以下結果

uid x y z 
+---+---+---+---+ 
| 1 | 3 | 4 | 5 | 
+---+---+---+---+ 
| 2 | 3 | 4 | 0 | 
+---+---+---+---+ 
| 3 | 3 | 4 | 0 | 
+---+---+---+---+ 

是否有功能或可以從多個行讀取數據,並把它列報表?

+7

閱讀有關'PIVOT'或*有條件聚集* – Shnugo

回答

2

您的數據存儲在一個名爲entity-attribute value(EAV)的結構中。 「扁平化」的一種方法是使用group bypivot

select uid, 
     max(case when nid = 'x' then val end) as x, 
     max(case when nid = 'y' then val end) as y, 
     max(case when nid = 'z' then val end) as z 
from t 
group by uid; 

如果你不知道你在結果表所需的特定值,那麼你需要動態SQL。該查詢更具挑戰性。我建議你從谷歌搜索「SQL Server動態數據透視表」開始。

+0

將這項工作如果VAL是不同的UID不同? – Nithin

+0

@Nithin。 。 。是。它將爲沒有值的ID返回NULL。 –

1

我們可以使用動態SQL

達到預期的結果
IF OBJECT_ID('Tempdb..#Temp') IS NOt NUll 
Drop Table #Temp 
;With cte(uid, nid, val) 
AS 
(
SELECT 1 , 'x', 3 UNION ALL 
SELECT 2 , 'x', 3 UNION ALL 
SELECT 3 , 'x', 3 UNION ALL 
SELECT 1 , 'y', 4 UNION ALL 
SELECT 2 , 'y', 4 UNION ALL 
SELECT 3 , 'y', 4 UNION ALL 
SELECT 1 , 'z', 5 
) 
SELECT * INTO #Temp FRom cte 

DECLARE @dynamicCol nvarchar(max), 
     @Sql nvarchar(max), 
     @dynamicCol2 nvarchar(max) 

SELECT @dynamicCol=STUFF((SELECT DISTINCT ', ' + 'ISNULL('+nid+',''0'') AS '+QUOTENAME(nid) FROM #Temp 
FOR XML PATH('')),1,1,'') 

SELECT @dynamicCol2=STUFF((SELECT DISTINCT ', ' + QUOTENAME(nid) FROM #Temp 
FOR XML PATH('')),1,1,'') 

SET @Sql=' 
      SELECT [uid] , '+ @dynamicCol +' From 
      (
      SELECT * From 
      #temp 
      )AS Src 
      PIVOT 
      (
      MAX([val]) For [nid ] IN ('[email protected]+') 
      ) 
      AS Pvt 
      ' 

PRINT @Sql 

EXEC(@Sql) 

輸出

uid x y z 
-------------- 
1 3 4 5 
2 3 4 0 
3 3 4 0 
相關問題