Вопрос о Crystal Reports + хранимая процедура SQL Server с GROUP BY
Я пишу отчет в Crystal Reports XI Developer, который выполняет хранимую процедуру в базе данных SQL Server 2005. Набор записей возвращает сводку из таблицы журнала, сгруппированной по дням и часам.
В настоящее время мой запрос выглядит примерно так:
SELECT
sum(colA) as "Total 1",
day(convert(smalldatetime, convert(float, Timestamp) / 1440 - 1)) as "Date",
datepart(hh, convert(smalldatetime, convert(float, Timestamp) / 1440 - 1)) as "Hour"
`etc...`
GROUP BY
Day, Hour
Не обращая внимания на безумие в отношении дат, я думаю, что разработчики систем сильно пили, когда они решали, как хранить свои даты.
Моя проблема заключается в следующем: поскольку не всегда есть записи по каждому часу дня, я получаю пробелы, что понятно, но я бы хотел, чтобы Crystal могла отчитываться за все 24 часа независимо от того, есть ли данные или нет.
Я знаю, что могу изменить это, поместив весь запрос в WHILE
цикл (внутри хранимой процедуры) и выполнение запросов в отдельные часы, но что-то внутри меня говорит, что один запрос лучше, чем 24.
Я хотел бы знать, есть ли способ заставить Crystal выполнять итерацию по часам дня, а не итерацию по строкам таблицы, как это обычно делается.
В качестве альтернативы, есть ли способ отформатировать запрос так, чтобы он включал пустые строки часа, не убивая мой сервер базы данных?
2 ответа
Вот как я решил эту проблему:
- Создайте локальную таблицу на вашем SQL-сервере. Назовите это "LU_Hours".
- Эта таблица будет иметь одно целое поле (называемое "Часы") с 24 строками. Конечно, значения будут от 1 до 24.
- Правильно присоедините это к существующему запросу.
- Возможно, вам придется настроить это, чтобы убедиться, что пустые часы обрабатываются в соответствии с вашими требованиями.
Вы можете использовать предложение WITH для создания 24 часов, а затем OUTER JOIN.
WITH hours AS (
SELECT 1 AS hour
UNION
SELECT 2 AS hour
...
SELECT 24 AS hour
)
SELECT *
FROM hours h
LEFT OUTER JOIN [your table] x ON h.hour=x.datepart(hh, convert(smalldatetime, convert(float, Timestamp) / 1440 - 1))
Этот SQL нужно добавить в команду.
Сгруппируйте по необходимости в SQL или отчете.