2016-03-29 3 views
0

Принимая во внимание, что это довольно общий вопрос SQL, я работаю в PostgreSQL 9.4 без возможности использовать другое программное обеспечение базы данных и поэтому прошу, чтобы любой ответ был совместим с его возможностями ,Несколько суммарных сумм из разных условий в одном запросе sql

Мне нужно вернуть несколько совокупных итогов из одного запроса, чтобы каждая сумма находилась в новой строке, и каждая из групп определялась уникальным интервалом времени, например. WHERE time_stamp BETWEEN '2016-02-07' AND '2016-02-14'. Количество записей, которые удовлетворяют этому предложению WHERE, неизвестно и может быть нулевым, и в этом случае в идеале результат равен «0». Это то, что я выработал до сих пор:

(
SELECT SUM(minutes) AS min 
FROM downtime 
WHERE time_stamp BETWEEN '2016-02-07' AND '2016-02-14' 
) 
UNION ALL 
(
SELECT SUM(minutes) 
FROM downtime 
WHERE time_stamp BETWEEN '2016-02-14' AND '2016-02-21' 
) 
UNION ALL 
(
SELECT SUM(minutes) 
FROM downtime 
WHERE time_stamp BETWEEN '2016-02-28' AND '2016-03-06' 
) 
UNION ALL 
(
SELECT SUM(minutes) 
FROM downtime 
WHERE time_stamp BETWEEN '2016-03-06' AND '2016-03-13' 
) 
UNION ALL 
(
SELECT SUM(minutes)) 
FROM downtime 
WHERE time_stamp BETWEEN '2016-03-13' AND '2016-03-20' 
) 
UNION ALL 
(
SELECT SUM(minutes) 
FROM downtime 
WHERE time_stamp BETWEEN '2016-03-20' AND '2016-03-27' 
) 

Результат:

 min 
---+----- 
1 | 119 
2 | 4 
3 | 30 
4 | 
5 | 62 
6 | 350 

Этот запрос получает меня почти точный результат, что я хочу; конечно, достаточно хорошо, что я могу сделать именно то, что мне нужно, с результатами. Временные интервалы без записей являются пустыми, но это было предсказуемо, и, хотя я бы предпочел «0», я мог бы учитывать пустые строки в программном обеспечении.

Но, хотя это не страшно в течение 6 недель, которые он представляет, я хочу быть гибким и иметь возможность делать то же самое для разных периодов времени и для другого количества точек данных, таких как каждый день в неделю, каждую неделю через 3 месяца, 6 месяцев, каждый месяц в 1 год, 2 года и т. д. Как написано выше, кажется, что это будет утомительно быстро ... например, 1 неделя охватывает более двух лет, составляет 104 подзапроса.

Что мне нужно - это более элегантный способ получить тот же (или похожий) результат.

Я также не знаю, является ли выполнение 104 итераций аналогичного запроса выше (против 6, которое он делает сейчас) является особенно эффективным использованием.

В конечном итоге я собираюсь написать код, который поможет мне построить (и, таким образом, абстрактный) длинный, уродливый запрос, - но было бы здорово иметь более сжатый и масштабируемый запрос.

+3

Я не думаю, что ваш запрос делает то, что вы думаете, что он делает. «МЕЖДУ» включено, поэтому границы включены. –

ответ

1

В Postgres, вы можете создать серию раз, а затем использовать их для агрегации:

select g.dte, coalesce(sum(dt.minutes), 0) as minutes 
from generate_series('2016-02-07'::timestamp, '2016-03-20'::timestamp, interval '7 day') g(dte) left join 
    downtime dt 
    on dt.timestamp >= g.dte and dt.timestamp < g.dte + interval '7 day' 
group by g.dte 
order by g.dte; 
+0

Спасибо, сэр. Позвольте мне немного поработать с ним, прежде чем я приму ваш ответ, но это, похоже, именно то, что я хотел. – Snowman

Смежные вопросы