Cómo consultar múltiples SUMs del mismo elemento utilizando SQL en iReport
-
05-07-2019 - |
Pregunta
-
Estoy creando un JasperReport utilizando iReport y, como tal, estoy limitado * a una consulta SQL.
-
Tengo una tabla de 'estadísticas', con un 'nombre' (VARCHAR), 'cuenta' (INTEGER) y columnas 'datetime' (DATETIME).
-
Es lo suficientemente simple para obtener la suma de la columna 'contar' cuando el 'nombre' era " prueba " para el último día, y de manera similar para la última semana y el mes (ver más abajo)
Declaración SQL de trabajo:
SELECT
SUM(count)as 'today'
FROM
statistics
WHERE
name = "test"
AND $P{oneDayAgo} <= datetime
AND datetime <= $P{now}
- Sin embargo, como solo tengo una declaración SQL con la que trabajar, necesito combinarlos de alguna manera. Intenté usar UNION (como a continuación) pero esto no funcionó.
Declaración SQL fallida:
SELECT
SUM(count)as 'today'
FROM
statistics
WHERE
name = "test"
AND $P{oneDayAgo} <= datetime
AND datetime <= $P{now}
UNION
SELECT
SUM(count)as 'thisWeek'
FROM
statistics
WHERE
name = "test"
AND $P{oneWeekAgo} <= datetime
AND datetime <= $P{now}
UNION
SELECT
SUM(count)as 'thisMonth'
FROM
statistics
WHERE
name = "test"
AND $P{oneMonthAgo} <= datetime
AND datetime <= $P{now}
(*) se pueden agregar consultas adicionales solo para gráficos o tablas cruzadas, ninguna de las cuales cumple mi propósito.
Solución
suma (caso cuando -condición- luego cuenta el final 0)
SELECT
SUM(case when $P{oneDayAgo} <= datetime then count else 0 end) as 'today',
SUM(case when $P{oneWeekAgo} <= datetime then count else 0 end) as 'thisweek',
SUM(count) as 'thismonth'
FROM
statistics
WHERE
name = "test"
AND $P{oneMonthAgo} <= datetime
AND datetime <= $P{now}
tenga en cuenta que si necesita promedios, asegúrese de sustituir NULL por 0.
Otros consejos
Las consultas UNION'd deberían producir las mismas columnas (nombre, tipo). Establezca las columnas no utilizadas en NULL o use una columna de diferenciación:
SELECT
SUM(count) as `total`,
'today' as `when`
FROM
statistics
WHERE
name = "test"
AND $P{oneDayAgo} <= datetime
AND datetime <= $P{now}
UNION
SELECT
SUM(count) as `total`,
'thisWeek' as `when`
FROM
statistics
WHERE
name = "test"
AND $P{oneWeekAgo} <= datetime
AND datetime <= $P{now}
UNION
SELECT
SUM(count) as `total`,
'thisMonth' as `when`
FROM
statistics
WHERE
name = "test"
AND $P{oneMonthAgo} <= datetime
AND datetime <= $P{now}
Tienes 2 opciones:
1) Elimine la parte 'como' de cada consulta y luego aparecerá como 1 columna que no tendrá un nombre
2) Crea una tabla temporal e inserta esas filas en una tabla temporal y luego consulta la tabla temporal