2010-06-23 5 views
6

Espero que alguien me pueda ayudar. Tengo una tabla que registra nuestros trabajos de importación. Necesito una consulta que produzca una matriz con los nombres de las tablas en el eje vertical, las fechas de importación en el eje horizontal y el número total de registros importados para esa tabla en esa fecha en la celda de la matriz. No me importa si tenemos que crear una tabla temporal, pero todo debe hacerse en MySQL.Pregunta de consulta de MySQL, no puedo obtenerlo

A continuación se muestra una muestra simplificada de nuestra tabla de registro de eventos. No solo tiene muchos más fieds, sino que importamos muchas más tablas. Por lo tanto, la solución debe explicar la consulta de los nombres de la tabla. Usted se dará cuenta de que los datos se pueden importar en una tabla más de una vez al día, al igual que en los registros 5 y 6.

id table_name import_date   num_recs 
----+-----------+--------------------+------- 
0 customer 2010-06-20 00:00:00 10   
1 order  2010-06-20 00:00:00 15   
2 customer 2010-06-21 00:00:00 5   
3 order  2010-06-21 00:00:00 6   
4 customer 2010-06-22 00:00:00 1   
5 order  2010-06-22 00:00:00 6   
6 order  2010-06-22 00:00:00 1   

que estamos buscando un resultado algo como esto. No tiene que ser exacto

table_name 06-20 06-21 06-22 
------------+-----+-----+------ 
customer | 10 | 5 | 1 
order  | 15 | 6 | 7 
+1

/me espera a escuchar acerca de cómo tiene que ser dinámicos fechas ... –

+1

Usted va a aceptar una de estas respuestas? – runrig

Respuesta

3

¿Qué pasa con la salida de la forma:

table_name date imports 
------------+-------+-------- 
customer | 06-20 | 10 
customer | 06-21 | 5 
order  | 06-20 | 15 
order  | 06-21 | 6 

De esta manera se puede hacer con un simple GROUP BY:

SELECT table_name, DATE(import_date) AS date, SUM(*) AS imports 
FROM yourTable 
GROUP BY table_name, date; 

De lo contrario, la consulta va a ser realmente desagradable.

+0

Bueno, importamos todas las noches. Mi gerente quiere un informe de consulta MySQL que se pueda ejecutar en cualquier momento para mostrar dicho historial de importación durante los últimos 30 días. –

+0

Y, sí, él quiere fechas dinámicas. –

+3

Es bastante posible hacer cosas inteligentes para convertir filas en columnas (evitaré hacer una crítica de las respuestas tratando de intentar esto hasta ahora) pero es la FORMA INCORRECTA DE RESOLVER EL PROBLEMA. Ve con la respuesta de Ben S. Si su trabajo depende de que usted lo proporcione en el diseño original y su jefe no tiene ** nada ** acerca de las bases de datos relacionales, ejecute la consulta desde MSExcel u OpenOffice y genere una tabla dinámica. Y empieza a buscar otro trabajo, porque muy pronto te pedirá que organices la primera misión tripulada a Marte usando muchas bandas de goma. – symcbean

2

MySQL no puede hacer consultas de pivote, pero se puede hacer en dos consultas basadas en los resultados de la primera consulta como SQL para la consulta siguiente:

SELECT 'SELECT table_name' 
UNION 
SELECT CONCAT(', SUM(IF(import_date = "',import_date,'", num_recs,0)) AS "',DATE_FORMAT(import_date, "%m-%d"),'"') 
FROM event_log 
GROUP BY import_date 
UNION 
SELECT 'FROM event_log GROUP BY table_name' 

luego ejecutar la salida de esa consulta a obtener sus resultados finales, por ejemplo por su ejemplo que se obtendría:

SELECT table_name               
, SUM(IF(import_date = "2010-06-20", num_recs,0)) AS "06-20" 
, SUM(IF(import_date = "2010-06-21", num_recs,0)) AS "06-21" 
, SUM(IF(import_date = "2010-06-22", num_recs,0)) AS "06-22" 
FROM event_log GROUP BY table_name 

Usted puede escribir un procedimiento almacenado para concatenar, preparar, y luego ejecutar los resultados de la primera consulta, o, si esto es todo lo ejecuta desde un script de shell, puede capture los resultados de la primera consulta, luego regrese los resultados a mysql.

+0

Consulte mi consulta sobre cómo hacerlo en una sola declaración. –

+0

Y eso no es SQL dinámico, solo las consultas necesarias. –

+0

No dije que era SQL dinámico. Simplemente una solución dinámica :-) Dado que la primera consulta devuelve más de una fila, no puede usar las declaraciones preparadas de mysql directamente, pero podría escribir un procedimiento almacenado para concatenar, preparar y luego ejecutar el resultado de la primera consulta.O simplemente podría capturar el resultado de la primera consulta desde un script de shell, y luego retroalimentarlo a mysql. – runrig

0

Creo que Ben S está en el camino correcto. Quería ofrecer lo que pude aquí en caso de que ayude a alguien, quién sabe. Original source

Aquí hay un método para tomar dos fechas arbitrarias y dividirlas en bloques de tiempo, y luego realiza alguna función de agregación en otros datos en cada bloque. En su caso, ese bloque probablemente sea un solo día, la fecha de inicio probablemente sea de 30 días antes del día actual, y la fecha de finalización probablemente sea el día actual. Cada bloque puede devolverse con algún indicador agregado de interés. En su caso, este será probablemente el SUM('imports')

SELECT t1.table_name AS table_name, t1.imports AS imports FROM (SELECT SUM(`imports`) AS imports, CEIL((UNIX_TIMESTAMP('<now>') - UNIX_TIMESTAMP(`import_date`))/ (<one day in ?seconds, i think?>)) AS RANGE FROM `<your table>` WHERE `import_date` BETWEEN '<now minus 30 days>' AND '<now>' GROUP BY RANGE ORDER BY RANGE DESC) AS t1;

Esto podría no ayuda en absoluto, pero si lo hace, entonces Goody. Se modifica fácilmente para devolver el día de inicio de cada rango como una columna de fecha. Para que quede claro, esto hace exactamente lo mismo que ofrece la solución de Ben S, pero funcionará si todas sus fechas no son 00:00:00, mientras que eso haría que su GROUP BY en la columna de fecha falle

Para ver cómo sería la devolución, ver la respuesta de Ben S y eliminar mentalmente la columna de fecha. Como dije, sin embargo, esa columna podría agregarse fácilmente a esta consulta.FWIW, he usado este método en tablas con más de 4 millones de filas y todavía se ejecuta en < 1 segundo, lo cual fue suficiente para mis propósitos.

Hamy

+0

El punto de las respuestas como Runrig's y el mío es que no tienes que hacer ese trabajo fuera de SQL, "eliminar mentalmente la columna de fecha". –

+0

¿No crees que no sé que me bajaste? ¿Puedes tener algo más infantil? –

+0

La solución, como algunos de ustedes mencionaron, son varias consultas y algunos procesos en PHP. –

Cuestiones relacionadas