Как запросить несколько SUM одного и того же элемента с помощью SQL в iReport

  • Я создаю JasperReport с помощью iReport, поэтому я ограничен* одним SQL-запросом.

  • У меня есть таблица «статистика» со столбцами «имя» (VARCHAR), «количество» (INTEGER) и «дата-время» (DATETIME).

  • Достаточно просто получить сумму столбца «количество», когда «имя» было «тестовым» за последний день, а также за последнюю неделю и месяц (см. ниже).

Рабочий оператор SQL:


SELECT
  SUM(count)as 'today'
FROM
  statistics
WHERE
   name = "test"
  AND $P{oneDayAgo} <= datetime
  AND datetime <= $P{now}
  • Однако, поскольку у меня есть только один оператор SQL для работы, мне нужно как-то их комбинировать. Я пытался использовать UNION (как показано ниже), но это не сработало.

Неудачная инструкция 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}

(*) можно добавлять дополнительные запросы только для графиков или кросс-таблиц, ни один из которых не подходит для моей цели.


person barryred    schedule 16.06.2009    source источник
comment
Если вы опубликуете определение таблицы и пример желаемого результата, я уверен, что кто-то может вам помочь...   -  person Eric Schneider    schedule 16.06.2009


Ответы (3)


сумма (случай, когда -условие- затем считать иначе 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}

обратите внимание, что если вам нужны средние значения, не забудьте заменить NULL на 0.

person Hafthor    schedule 16.06.2009
comment
$P{} - это магия Jasper или какая-то часть языка SQL, которую я никогда раньше не видел? - person Chris K; 16.06.2009
comment
$P{} — это магия Джаспера! (просто параметр, указанный в отчете) - person barryred; 18.06.2009
comment
Круто, спасибо, Хафтор, я понятия не имею, «быстрее» это или «лучше», но это определенно чище и понятнее. - person barryred; 18.06.2009

Запросы UNION должны создавать одни и те же столбцы (имя, тип). Установите для неиспользуемых столбцов значение NULL или используйте столбец дифференциации:

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}
person instanceof me    schedule 16.06.2009
comment
Итак, как мне отличить «день» от «недели» от строк «месяц»? - person barryred; 16.06.2009
comment
Вы также можете использовать CASE/WHEN для вычисления столбца «когда» вместо UNION. - person instanceof me; 16.06.2009
comment
Это решение даст вам 3 строки по 2 столбца (3 всего и 3 когда). Hafthor's даст вам одну строку с 3 столбцами, может быть, предпочтительнее. - person instanceof me; 16.06.2009

У вас есть 2 варианта:

1) Удалите часть «как» каждого запроса, и тогда он будет представлен как 1 столбец, у которого не будет имени.

2) Создайте временную таблицу и вставьте эти строки в временную таблицу, а затем запросите временную таблицу.

person Avitus    schedule 16.06.2009