2012-08-31 25 views
16

Ok Mam tabeli, który wygląda takT-SQL dynamiczne pivot

ItemID | ColumnName | Value 
1  | name  | Peter 
1  | phone  | 12345678 
1  | email  | [email protected] 
2  | name  | John 
2  | phone  | 87654321 
2  | email  | [email protected] 
3  | name  | Sarah 
3  | phone  | 55667788 
3  | email  | [email protected] 

Teraz trzeba włączyć, że w ten sposób:

ItemID | name | phone | email 
1  | Peter | 12345678 | [email protected] 
2  | John | 87654321 | [email protected] 
3  | Sarah | 55667788 | [email protected] 

czekałem na dynamicznych przykładów przestawnych, ale wydaje się, że nie jestem w stanie dopasować ich do mojego scenariusza.

Czy ktoś może pomóc?

+0

ja nie widzę pivot w Twoich danych. W pierwszym bloku zostały wymienione regularne nazwy i wartości kolumn, a zwykle w drugim. – IamIC

+0

A jeśli pierwszy blok reprezentuje twoje rzeczywiste dane, to dlaczego jest przechowywany w ten sposób w przeciwieństwie do znormalizowanego? – IamIC

+0

Dlaczego potrzebujesz dynamicznego PIVOT dla tych danych? Można to osiągnąć za pomocą statycznego PIVOTA (sprawdź moją odpowiedź). Czy to dlatego, że oczekujesz, że ColumnName ma wartości inne niż imię i nazwisko, numer telefonu i adres e-mail? – Kash

Odpowiedz

26

Wystarczy popatrzeć na poniższym przykładzie

CREATE TABLE #Table (
     ID INT, 
     ColumnName VARCHAR(250), 
     Value VARCHAR(250) 
) 

INSERT INTO #Table SELECT 1,'name','Peter' 
INSERT INTO #Table SELECT 1,'phone','12345678' 
INSERT INTO #Table SELECT 1,'email','[email protected]' 
INSERT INTO #Table SELECT 2,'name','John' 
INSERT INTO #Table SELECT 2,'phone','87654321' 
INSERT INTO #Table SELECT 2,'email','[email protected]' 
INSERT INTO #Table SELECT 3,'name','Sarah' 
INSERT INTO #Table SELECT 3,'phone','55667788' 
INSERT INTO #Table SELECT 3,'email','[email protected]' 

---I assumed your tablename as TESTTABLE--- 
DECLARE @cols NVARCHAR(2000) 
DECLARE @query NVARCHAR(4000) 

SELECT @cols = STUFF((SELECT DISTINCT TOP 100 PERCENT 
           '],[' + t.ColumnName 
         FROM #Table AS t 
         --ORDER BY '],[' + t.ID 
         FOR XML PATH('') 
        ), 1, 2, '') + ']' 

SELECT @cols 

SET @query = N'SELECT ID,'+ @cols +' FROM 
(SELECT t1.ID,t1.ColumnName , t1.Value FROM #Table AS t1) p 
PIVOT (MAX([Value]) FOR ColumnName IN ('+ @cols +')) 
AS pvt;' 

EXECUTE(@query) 

DROP TABLE #Table 
+0

Wielkie dzięki, właśnie tego szukałem! –

+0

Działa świetnie! :) –

-1

Oto kwerendy używam mojego contactlist :)

SELECT * 
FROM 
    (
    SELECT Contact_Id AS CT 
      , [Age] 
      , [Sex] 
      , [State] 
      , [Country] 
      , [Keyword] 
      , [Married] 
      , [Kids] 
      , [Car] 
    FROM 
     (SELECT c.PropertyName 
       , c.ValueString 
       , c.Contact_Id 
      FROM 
       ContactProfiles c) AS ctp 
     PIVOT (max(ctp.ValueString) FOR PropertyName IN ([Age], [Sex], [State], [Country], [Keyword], [Married], [Kids], [Car])) AS PivotTable 
     ) AS pvt 

WHERE 
    pvt.[Age] > 18 
    AND (pvt.[State] = 'CA' OR pvt.[State] = 'NY') 
    AND pvt.[Sex] = 'F' 
    --*AND pvt.[Keyword] LIKE '%B;%' 
    AND pvt.[Married] = 'True' 
    AND pvt.[Kids] > 0 
0

Nie potrzeba dynamicznego pivot, ponieważ posiadał będzie to inna tabela. Po prostu zrobić coś takiego:

name phone email 
--------------------------------- 
Peter    
     123456 
       [email protected] 

Sprawdź to SQL fiddle

SELECT DISTINCT u.ItemID, n.Value as 'name', p.Value as 'phone', e.Value as 'email' 
FROM UserData u 
INNER JOIN(
SELECT ItemID, Value 
FROM UserData WHERE ColumnName = 'name') n ON n.ItemID = u.ItemID 
INNER JOIN(
SELECT ItemID, Value 
FROM UserData WHERE ColumnName = 'phone') p ON p.ItemID = u.ItemID 
INNER JOIN(
SELECT ItemID, Value 
FROM UserData WHERE ColumnName = 'email') e ON e.ItemID = u.ItemID 
+2

Problem polega na tym, że kolumny ColumnNames są dynamiczne. Zarówno ich nazwy, jak i liczba kolumn będą się różnić. –

3

spróbuj tego:

SQL Server 2005+

;with 
     cte_name as(select * from <table> where ColumnName='name'), 
     cte_phone as(select * from <table> where ColumnName='phone'), 
     cte_email as(select * from <table> where ColumnName='email') 
    select n.ItemID,n.Value [Name],p.Value [Phone],e.Value [Email] 
    from cte_name n 
    join cte_phone p 
    on n.ItemID=p.ItemID 
    join cte_email e 
    on n.ItemID=e.ItemID 


SQL Fiddle Demo

-1

Czy próbowałeś to:

SELECT ItemID, name, phone, email 
FROM 
(SELECT [ItemID] ,[ColumnName] ,[Value] FROM Item) Item 
PIVOT (MAX(Value) FOR ColumnName IN (name, phone, email)) as pvt 
+2

Problem polega na tym, że kolumny ColumnNames są dynamiczne. Zarówno ich nazwy, jak i liczba kolumn będą się różnić. –