2017-06-20 3 views
0

Ich bin ein Anfänger mit SQL und habe eine Frage. Ich habe eine Tabelle mit Benutzerdaten wie dieseSQL Server Zeilen aus der Tabelle und Anzeige in Spalten

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

Wo uid eine Benutzer-ID, nid ist ein Name, ID, die einen Wert zu identifizieren und val ist der tatsächliche Wert.

Ich möchte eine Abfrage schreiben, die folgendes Ergebnis

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

Gibt es Funktionen oder Anweisungen gibt, die Daten aus mehreren Zeilen lesen kann und es in Spalten setzen?

+7

Lesen Sie mehr über 'PIVOT' oder * bedingte Aggregation * – Shnugo

Antwort

2

Ihre Daten werden in einer Struktur namens Entity-Attribut-Wert (EAV) gespeichert. Eine Möglichkeit, „Abflachung“ es ist zu verwenden group by oder pivot:

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; 

Wenn Sie nicht über die spezifischen Werte kennen Sie in der Ergebnistabelle wollen, dann müssen Sie die dynamische SQL. Die Abfrage ist ein bisschen schwieriger. Ich würde vorschlagen, dass Sie mit "SQL Server Dynamic Pivot" googeln beginnen.

+0

Wird diese Arbeit, wenn die val für unterschiedliche uid unterschiedlich sind? – Nithin

+0

@Nithin. . . Ja. Es wird 'NULL' für die IDs zurückgeben, die keinen Wert haben. –

1

Wir können Wunsch erreichen Ergebnis mit Dynamic 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) 

OutPut

uid x y z 
-------------- 
1 3 4 5 
2 3 4 0 
3 3 4 0 
Verwandte Themen