我有类似下表的内容:
================================================
| 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 | jane@email.com |
------------------------------------------------
我需要一个能给我这样结果的查询:
==================================================
| UserId | Username | Password | Email Address |
=========+===========+===========================|
| 100 | John Doe | pass123! | |
|--------+-----------+----------+----------------|
| 102 | Jane | $ecret | jane@email.com |
|--------+-----------+----------+----------------|
请注意,FieldName中的值不限于用户名,密码和电子邮件地址。它们可以是用户定义的任何东西。
有没有办法在SQL中执行此操作?
答案 0 :(得分:37)
MySQL不支持ANSI PIVOT / UNPIVOT语法,因此您可以使用:
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
如您所见,CASE语句需要按值定义。要使此动态,您需要使用MySQL's Prepared Statement (dynamic SQL) syntax。
答案 1 :(得分:1)
您可以使用GROUP_CONCAT
(未经测试)
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