2012-06-07 17 views
21

Tengo una tabla legado de la información del usuario (que todavía está en uso activo) y no se puede cambiar la estructura de -MySQL seleccionar valores de las filas dinámicas como nombres de columna, otra columna como valor

id name  value 
------------------------------ 
0  timezone Europe/London 
0  language en 
0  country 45 
0  something x 
1  timezone Europe/Paris 
1  language fr 
1  country 46 

zona horaria/idioma/etc país son sólo ejemplos de nombres, que pueden ser variables/no existe una lista finita que no sea única en filas de esa columna

necesito una consulta SQL compatibles MySQL que devolvería -

id timezone  language country something 
--------------------------------------------------- 
0  Europe/London en   45  x 
1  Europe/Paris fr   46 

He revisado varias respuestas en stackoverflow para hackear la funcionalidad de la tabla pivote en MySQL y similares, pero ninguna de ellas parece coincidir con el uso de alias de nombre de columna variable a partir de valores de fila únicos de una columna de la misma tabla. A pesar de que he dormido poco, así que todos comienzan a ser un poco borrosos, se disculpa de antemano.

más cercano que pude encontrar sería usar comandos preparados https://stackoverflow.com/a/986088/830171 que primero obtener todos los valores posibles/únicos de la columna nombre y construir una consulta que utiliza CASE WHEN, y/o múltiples sub SELECT o en JOIN mismas consultas de tabla.

Las alternativas que puedo pensar serían obtener todas las filas para esa identificación de usuario y procesarlas en la propia aplicación en un for-loop, o intentar limitar los nombres a una cantidad finita y usar sub- SELECT s/JOIN s. Sin embargo, esa segunda opción no es ideal si se agrega un nuevo nombre. Tendría que volver a visitar esta consulta.

Por favor, dime que he perdido algo obvio

+0

¿Realmente necesita que esto se exprese en 'sql' o el postprocesamiento será suficiente con su lenguaje de programación de elección? Si necesita unirse a sus datos deshumidificados, entonces una vista/proc podría ser el truco. – bluevector

+0

Yeh Mantendré el desorden en el nivel de la aplicación por ahora. Conseguiré todas las filas para esa identificación de usuario y recorreré la colocación de datos en una matriz asociativa. Solo quería comprobar que esa era la única buena opción. Todavía es muy útil tener el método SQL para migraciones e informes únicos. – gingerCodeNinja

Respuesta

39

A diferencia de otros RDBMS MySQL no tiene soporte nativo para las operaciones de este tipo pivotante por diseño (los desarrolladores creen que es más adecuado para la presentación, en lugar que la base de datos, capa de tu aplicación).

Si es absolutamente necesario perfom tales manipulaciones dentro de MySQL, la construcción de una declaración preparada es el camino a seguir — aunque en lugar de jugar un poco con CASE, probablemente sólo tiene que utilizar GROUP_CONCAT() función de MySQL:

SELECT CONCAT(
    'SELECT `table`.id', GROUP_CONCAT(' 
    , `t_', REPLACE(name, '`', '``'), '`.value 
     AS `', REPLACE(name, '`', '``'), '`' 
    SEPARATOR ''), 
' FROM `table` ', GROUP_CONCAT(' 
    LEFT JOIN `table` AS `t_', REPLACE(name, '`', '``'), '` 
      ON `table`.id = `t_', REPLACE(name, '`', '``'), '`.id 
      AND `t_', REPLACE(name, '`', '``'), '`.name = ', QUOTE(name) 
    SEPARATOR ''), 
' GROUP BY `table`.id' 
) INTO @qry FROM (SELECT DISTINCT name FROM `table`) t; 

PREPARE stmt FROM @qry; 
EXECUTE stmt; 

Ver en sqlfiddle.

Tenga en cuenta que el resultado de GROUP_CONCAT() está limitado por la variable group_concat_max_len (valor predeterminado de 1024 bytes: es poco probable que sea relevante aquí a menos que tenga valores extremadamente largos name).

+4

wow - gracias por hacer todo el esfuerzo de escribir y probar una solución. Muy apreciado. Siempre quise saber cómo hacer este tipo de consultas y parece tan complicado como imaginaba. Por ahora, mantendré el desorden en el nivel de la aplicación, pero esta consulta seguirá siendo muy útil para informes y migraciones. Gracias. – gingerCodeNinja

+0

Tengo un escenario muy similar y obtengo el resultado pivote bien, usando su excelente ejemplo.Pero necesito que el resultado se almacene en una tabla, ya que quiero generar un gráfico a partir de ella. ¿Es posible almacenar el resultado pivotado en una tabla? Además, ¿es posible ejecutar arriba en Php? Mi tabla fuente es usuario, fecha, rendimiento y pivote es usuario como filas, fecha como columnas y rendimiento como valores de celda. – Sri

+0

He puesto mi tabla de ejemplo en sqlfiddle (consulte http://sqlfiddle.com/#!2/06be4/1) – Sri

Cuestiones relacionadas