2012-04-02 13 views
5

Tengo un sistema basado en una base de datos MySQL relacional que permite a las personas almacenar detalles de "clientes potenciales". Además, las personas pueden crear sus propias columnas para almacenar datos y luego, al agregar cuentas nuevas, pueden agregar datos debajo de ellas. La estructura de la tabla es el siguiente:¿Cómo recuperar los atributos "dinámicos" almacenados en varias filas como registros normales?

Leads - Identificación, correo electrónico, user_id

ATRIBUTOS - Identificación, attr_name, user_id

ATTR_VALUES - lead_id, attr_id, valor, user_id

Obviamente, en estas tablas, "user_id" hace referencia a una tabla de "Usuarios" que solo contiene personas que pueden iniciar sesión en el sistema.

Estoy escribiendo una función para dar salida a los detalles del lead y actualmente estoy repasando los detalles básicos del lead como una consulta, y luego revisando cada atributo asociado con ese lead (uniéndome a la tabla de atributos para obtener el nombre) y luego unirse a las matrices en PHP. Esto es un poco complicado, y me preguntaba si había una manera de hacer esto en una consulta SQL. He leído un poco sobre algo llamado "mesa pivote", pero me cuesta entender cómo funciona.

Cualquier ayuda sería muy apreciada. ¡Gracias!

+0

MySql no es compatible con los comandos de Pivot. Eh, es gratis. – McGarnagle

+0

@dbase (microsoft?) Hombre: no * "Eh, es gratis" *, pero * "Eh, es una base de datos" * (a diferencia de ...). Los comandos de pivote no pertenecen a la base de datos, sino al nivel de presentación. – TMS

+0

Una buena pregunta, aunque el título fue engañoso: es posible en una sola consulta con bastante facilidad, solo suele unir todas las tablas, pero eso no es lo que probablemente desee. Editado el título. – TMS

Respuesta

0

Me gustaría echar un vistazo a este link. Que explican la fundamental de un pivote:

"tabla dinámica" o un "informe de tabla de referencias cruzadas" funciones características de SQL: DO sin "si", "caso", o "GROUP_CONCAT". Sí, hay un uso para esto ... las declaraciones "if" a veces causan problemas cuando se usan en la combinación . El secreto simple, y también es por qué funcionan en casi todas las bases de datos, es las siguientes funciones: sign (x) devuelve -1,0, +1 para valores x < 0, x = 0, x> 0 respectivamente abs (signo (x)) devuelve 0 si x = 0, si no, 1 si x> 0 o x < 0 1-abs (signo (x)) complemento de la anteriormente, dado que esto devuelve 1 sólo si x = 0

También se explica una forma más simple de exámenes pivotantes. Tal vez esto puede arrojar algo de luz sobre eso?

1

Usted podría hacer el giro en una sola consulta como la siguiente:

select l.id lead_id, 
     l.email, 
     group_concat(distinct case when a.attr_name = 'Home Phone' then v.value end) HomePhone, 
     ... 
from leads l 
left join attr_values v on l.id = v.lead_id 
left join attributes a on v.attr_id = a.id 
group by l.id 

Usted tendrá que incluir un campo group_concat derivada de separado para cada atributo que desea mostrar.

0

Lo que probablemente desee de mysql es hacer un valor sql (attr_name en su caso) una columna. Este principio se llama pivot table (a veces también tablas cruzadas o consultas cruzadas) y no es compatible con mysql. No porque mysql sea insuficiente, sino porque la operación pivote no es una operación de base de datos: el resultado no es una tabla de base de datos normal y es no diseñado para otras operaciones de bases de datos.El único propósito de la operación pivotante es una presentación, por eso pertenece a la capa de presentación, no a la base de datos.

Por lo tanto, cada solución de tratar de obtener una tabla dinámica de mysql siempre será hacky. Lo que recomiendo es conseguir que los datos de la base de datos en formato normal, simplemente haciendo algo como:

select * 
from attr_values join attributes using on attr_id = attributes.id 
    join leads on leads.id = lead_id 

y luego transformar la salida de la base de datos en el idioma de presentación (PHP, JSP, Python o lo que sea que se use).

0

Tendré cuidado al suponer que el pivote alcanzará su objetivo de simplificación. Pivot solo funcionará si tu attr_name es consistente. Como usted ha vinculado un ID de usuario, supongo que no. Además, tendrá múltiples valores para un attr_name. Me temo que la tabla dinámica no produciría el resultado que está buscando.

Le sugiero que mantenga sus tablas transaccionales y de informes separadas. Tenga una rutina ETL que limpie (es decir, haga que attr_name y attr_value) sean consistentes a través de la traducción. Esto hará que sus informes sean más significativos.

En resumen, para obtener resultados inmediatos para el usuario final, PHP es lo mejor que puede hacer. Para informar, transforme el EAV en una fila/columna primero antes de intentar informar sobre él.

Cuestiones relacionadas