2010-08-03 23 views
9

Tôi có một cái gì đó tương tự như bảng sau:SQL - Cách chuyển đổi?

================================================ 
| Id | UserId | FieldName  | FieldValue  | 
=====+========+===============+================| 
| 1 | 100 | Username  | John Doe  | 
|----+--------+---------------+----------------| 
| 2 | 100 | Password  | pass123!  | 
|----+--------+---------------+----------------| 
| 3 | 102 | Username  | Jane   | 
|----+--------+---------------+----------------| 
| 4 | 102 | Password  | $ecret   | 
|----+--------+---------------+----------------| 
| 5 | 102 | Email Address | [email protected] | 
------------------------------------------------ 

Tôi cần một truy vấn mà sẽ cung cấp cho tôi một kết quả như thế này:

================================================== 
| UserId | Username | Password | Email Address | 
=========+===========+===========================| 
| 100 | John Doe | pass123! |    | 
|--------+-----------+----------+----------------| 
| 102 | Jane  | $ecret | [email protected] | 
|--------+-----------+----------+----------------| 

Lưu ý rằng các giá trị trong FieldName không giới hạn Username, Mật khẩu và địa chỉ email. Chúng có thể là bất kỳ thứ gì vì chúng được người dùng định nghĩa.

Có cách nào để thực hiện việc này trong SQL không?

+0

thấy http://stackoverflow.com/questions/649802/how-to-pivot-a-mysql-entity-attribute-value- lược đồ cho một câu hỏi tương tự. Không thể thực hiện việc xoay vòng trong ứng dụng và để truy vấn thẳng về phía trước? Nếu bạn cần N thuộc tính, bạn sẽ cần tạo truy vấn động. –

Trả lời

24

MySQL không hỗ trợ ANSI PIVOT/cú pháp UNPIVOT, do đó để lại cho bạn để sử dụng:

SELECT t.userid 
     MAX(CASE WHEN t.fieldname = 'Username' THEN t.fieldvalue ELSE NULL END) AS Username, 
     MAX(CASE WHEN t.fieldname = 'Password' THEN t.fieldvalue ELSE NULL END) AS Password, 
     MAX(CASE WHEN t.fieldname = 'Email Address' THEN t.fieldvalue ELSE NULL END) AS Email 
    FROM TABLE t 
GROUP BY t.userid 

Như bạn có thể thấy, những điều khoản TRƯỜNG HỢP cần phải được xác định cho mỗi giá trị. Để thực hiện điều này, bạn cần sử dụng MySQL's Prepared Statement (dynamic SQL) syntax.

+0

Điểm của 'MAX' trong truy vấn này là gì? – KLee1

+0

@KLee - Vì vậy, anh ta không phải nhóm theo các cột đó – dcp

+0

@ KLee1: Bởi vì tuyên bố trường hợp không bằng phẳng truy vấn - sẽ có số không ở các vị trí khác nhau. Vì vậy, bạn phải sử dụng GROUP BY để làm phẳng truy vấn - MAX có giá trị cao nhất và bất kỳ thứ gì cao hơn NULL. –

1

Bạn có thể sử dụng GROUP_CONCAT

(chưa được kiểm tra)

SELECT UserId, 
GROUP_CONCAT(if(fieldname = 'Username', fieldvalue, NULL)) AS 'Username', 
GROUP_CONCAT(if(fieldname = 'Password', fieldvalue, NULL)) AS 'Password', 
GROUP_CONCAT(if(fieldname = 'Email Address', fieldvalue, NULL)) AS 'Email Address', 
FROM table 
GROUP BY UserId 
+1

Rủi ro vì nếu phần ELSE không trả về NULL, GROUP_CONCAT sẽ trả về một danh sách được phân cách bằng dấu phẩy. –

Các vấn đề liên quan