У меня есть представление в SQL Server Express, которое показывает общие значения, свернутые по дате.
Ниже показано, как на данный момент построено представление.
SELECT
COALESCE(MACH, 'Total') AS MACH,
COALESCE(DATE, '') AS 'DATE',
SUM(VAL) AS VAL
FROM
myTable
GROUP BY
ROLLUP (MACH, DATE)
HAVING
(MACH IS NULL) OR (DATE <> '')
Внутри myTable у меня есть эти события:
| MACH | DATE | TIME | VAL |
| 1 | 02/05/2024 | 17:35:17 | 100 |
| 1 | 02/05/2024 | 19:35:17 | 100 |
| 2 | 02/05/2024 | 21:35:17 | 100 |
| 1 | 03/05/2024 | 04:35:17 | 100 |
| 2 | 03/05/2024 | 05:35:17 | 100 |
| 1 | 03/05/2024 | 07:35:17 | 100 |
и мой взгляд такой:
| MACH | DATE | VAL |
| 1 | 02/05/2024 | 200 |
| 1 | 03/05/2024 | 200 |
| 2 | 02/05/2024 | 100 |
| 2 | 03/05/2024 | 100 |
| Total | | 600 |
Я хочу объединить две даты в одну, когда myTable.TIME будет раньше 06:00. Тогда вид должен выглядеть следующим образом:
| MACH | DATE | VAL |
| 1 | 02/05/2024 | 300 |
| 1 | 03/05/2024 | 100 |
| 2 | 02/05/2024 | 200 |
| Total | | 600 |
Является ли это возможным? Я пробовал использовать CASE WHEN внутри ROLLUP, но безуспешно и не могу понять, как это сделать.
Да, но я хочу иметь строки со временем до 6:00, чтобы результат был таким, как если бы они были накануне.
А, я вижу, извини. rollup (MACH, iif (TIME < '06:00', DATE-1, DATE)) должно работать? Не уверен насчет обозначения времени.
(MACH IS NULL) OR (DATE <> '') разве это не должно быть в WHERE? Ни в одном из этих пунктов нет агрегирования.
@ThomA нужно удалить промежуточные итоги.
Тогда, возможно, вы хотите GROUPING SETS, а не ROLLUP.
@BenderBoy Извините, мой вопрос был не очень ясен. Я попробовал ваше решение, но получаю сообщение об ошибке: «Столбец «DATE» недействителен в предложении HAVING, поскольку он не содержится ни в агрегатной функции, ни в предложении GROUP BY».
@Думе, да, нужно поставить iif в select, а в having это немного раздражает. Посмотрите мой ответ ниже, чтобы получить полное решение. Я думаю, это то, что вам нужно. Ваше здоровье
@ThomA, ты прав, здесь лучше группировать наборы. Я использовал объединение, потому что моей первоначальной идеей было создать строку для разделения каждой группы, но я передумал, потому что не хочу видеть промежуточные итоги. Знаете ли вы, как заменить промежуточные итоги на Null?
Кажется, у тебя появился новый вопрос, @Dume. Не забудьте предоставить образцы данных и ожидаемые результаты в доступном формате вместе с описанием ваших попыток, когда вы спросите.


Я думаю, лучше иметь внутренний выбор, который объединяет дату и время и преобразует их в DateTime, Затем вычтите из результата 6 часов, Это означает, что вы рассчитываете свой день от 6 утра до 6 утра следующего дня. Я надеюсь, что это поможет решить вашу проблему.
Здесь я переместил соответствующие вычисления в подзапрос, чтобы вам не пришлось повторять их три раза. Как видите, это просто «если время до 06:00, используйте предыдущий день»:
select
coalesce(MACH, 'Total') AS MACH,
RollupDate AS 'DATE',
sum(VAL) AS VAL
from
(select *, iif (TIME < '06:00', dateadd(day, -1, DATE), DATE) as RollupDate
from ##MyTable) X
group by
rollup (MACH, RollupDate)
having
RollupDate is not null
Извините, я не могу понять желаемый результат. Ваш
group byуже суммирует данные по дате независимо от времени?