2010-08-03 10 views
9

que tienen algo similar a la tabla siguiente:SQL - ¿Cómo transponer?

================================================ 
| 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] | 
------------------------------------------------ 

necesito una consulta que me dará un resultado como este:

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

Tenga en cuenta que los valores en NombreCampo no se limitan a nombre de usuario, Contraseña y dirección de correo electrónico. Pueden ser cualquier cosa, ya que están definidas por el usuario.

¿Hay alguna manera de hacer esto en SQL?

+0

ver http://stackoverflow.com/questions/649802/how-to-pivot-a-mysql-entity-attribute-value- esquema para una pregunta similar. ¿Es imposible hacer pivotes en la aplicación y dejar la consulta directa? Si va a necesitar N atributos, deberá generar la consulta dinámicamente. –

Respuesta

24

MySQL no soporta ANSI PIVOT sintaxis/UNPIVOT, para que deje su uso:

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 

Como se puede ver, las instrucciones CASE necesita ser definido por el valor. Para que esto sea dinámico, necesitarás usar MySQL's Prepared Statement (dynamic SQL) syntax.

+0

¿Cuál es el punto del 'MAX' en esta consulta? – KLee1

+0

@KLee - De modo que no tiene que agrupar por esas columnas – dcp

+0

@ KLee1: Como la declaración de caso no completa la consulta, habrá nulos en varios puntos. Por lo tanto, debe usar GROUP BY para aplanar la consulta: MAX toma el valor más alto y cualquier valor es superior a NULL. –

1

Usted podría utilizar GROUP_CONCAT

(no probado)

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

Arriesgado porque si la parte ELSE no devolvió NULL, GROUP_CONCAT devolverá una lista delimitada por comas. –

Cuestiones relacionadas