2012-08-31 33 views
16

Ok Tôi có một bảng trông như thế nàyT-SQL động trục

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] 

Bây giờ tôi cần phải biến chúng thành này:

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

Tôi đã được nhìn vào ví dụ trục động, nhưng có vẻ như Im không thể phù hợp với họ trong kịch bản của tôi.

Có ai giúp được không?

+0

Tôi không thấy một trục trong dữ liệu của bạn. Bạn đã liệt kê các tên và giá trị cột thông thường theo cách kỳ lạ trong khối đầu tiên và thông thường trong cột thứ hai. – IamIC

+0

Và nếu khối đầu tiên đại diện cho dữ liệu thực tế của bạn thì tại sao nó được lưu trữ như vậy chứ không phải chuẩn hóa? – IamIC

+0

Tại sao bạn cần một PIVOT động cho dữ liệu này? Điều này có thể đạt được bằng một PIVOT tĩnh (kiểm tra câu trả lời của tôi). Có phải vì bạn đang mong đợi ColumnName có các giá trị khác ngoài tên, điện thoại và email không? – Kash

Trả lời

26

Hãy nhìn vào ví dụ sau

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

Cảm ơn rất nhiều, đó là chính xác những gì tôi đang tìm kiếm! –

+0

Hoạt động tuyệt vời! :) –

-1

Dưới đây là một truy vấn Tôi đang sử dụng cho contactlist của tôi :)

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

Bạn không cần trục động, bởi vì nó sẽ là một bảng khác. Đơn giản chỉ cần làm một cái gì đó như thế này:

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

Kiểm tra này 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

Vấn đề là các ColumnNames là năng động. Cả tên và số cột sẽ khác nhau. –

3

thử điều này:

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

Các bạn đã thử này:

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

Vấn đề là các ColumnNames là động. Cả tên và số cột sẽ khác nhau. –