Comment interroger plusieurs SUM du même élément à l'aide de SQL dans iReport
-
05-07-2019 - |
Question
-
Je crée un JasperReport à l'aide d'iReport et, à ce titre, je suis limité * à une requête SQL.
-
J'ai une table "statistiques", avec des colonnes "nom" (VARCHAR), "compte" (INTEGER) et "date / heure" (DATETIME).
-
Il est assez simple d’obtenir la somme de la colonne "compte" lorsque le "nom" était "test". pour le dernier jour et de la même manière pour la semaine et le mois précédents (voir ci-dessous)
Instruction SQL de travail:
SELECT
SUM(count)as 'today'
FROM
statistics
WHERE
name = "test"
AND $P{oneDayAgo} <= datetime
AND datetime <= $P{now}
- Cependant, comme je n'ai qu'une seule instruction SQL à utiliser, je dois les combiner d'une manière ou d'une autre. J'ai essayé d'utiliser UNION (ci-dessous), mais cela n'a pas fonctionné.
Echec de l'instruction SQL:
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}
(*), vous pouvez ajouter des requêtes supplémentaires uniquement pour les graphiques ou les tableaux croisés, qui ne servent à rien.
La solution
sum (cas où -condition- puis compte 0 sinon)
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}
Notez que si vous avez besoin de moyennes, veillez à remplacer NULL par 0.
Autres conseils
Les requêtes UNION doivent générer les mêmes colonnes (nom, type). Définissez les colonnes inutilisées sur NULL ou utilisez une colonne de différenciation:
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}
Vous avez 2 options:
1) Supprimez la partie "en tant que" de chaque requête, elle se présentera sous la forme d'une colonne sans nom
2) Créez une table temporaire et insérez ces lignes dans une table temporaire, puis interrogez-la