SQL Запрос на подсчет элементов в диапазоне дат? - PullRequest
0 голосов
/ 12 февраля 2020

Для начала я достаточно знаю, чтобы попасть в беду. Я работаю над написанием запроса для системы AS / 400. У меня есть файл, который содержит дату начала и дату окончания. Что я хочу сделать, это создать запрос, который может подсчитать, сколько позиций было открыто за диапазон дат. (для моего приложения открытый определяется как: DATE > START_DATE И (DATE <= END_DATE OR END_DATE = '0')). Я могу заставить это работать для ручной установки «ДАТЫ», но я пытаюсь go назад и исторически вытаскивать эту информацию. У меня проблемы с запуском этого запроса к списку дат. Я хочу ввести исторический интервал (скажем, CURRENT_DATE - 5) и вывести:

Date             Open
20200206         30,000
20200207         31,000
20200210         29,675
20200211         31,375
20200212         32,000

Что я использую для запроса «один день за раз»:

SELECT
        COUNT(*) 
    FROM
        MYFILE
    WHERE 
        START_DATE < '20200210' 
    AND (
            END_DATE >= '20200210' 
        OR  END_DATE = '0'
        )

Это прекрасно работает, но занимает много времени. Отсюда я понятия не имею, как перейти к желаемому результату ... или даже если это возможно ... но это ускорит процесс для меня. Заранее спасибо.

PS Любая помощь приветствуется, если вы знаете, как выполнить sh в mySQL et c. Поделись, пожалуйста. Я могу взять это и использовать с точки зрения того, чтобы заставить его работать специально для AS / 400. Вот как я добрался до того места, где я сейчас нахожусь.

**************** Редактировать для уточнения 1. Текущий код Предоставлен код текущего дня это все что у меня есть. Я не знаю, с чего начать то, что я прошу. 2. Пример данных:

Line Item       START_DATE        END_DATE
1               20200206          20200210
2               20200207          20200210
3               20200207          20200207
Ожидаемый результат:
DATE           COUNT
20200205       0
20200206       0
20200207       1
20200210       2
20200211       0
СУБД Я обновил тег для включения DB2. 5. Я не верю, что GROUP BY сработает.
По сути, я ищу, чтобы это рассчитывалось в итеративном стиле. Исходя из моего питона / java фона, это имеет смысл для меня. Я не ищу все, что было открыто 5 дней go, я хочу начать 5 дней go и рассчитать, сколько позиций было открыто каждый из этих 5 дней. Если это действительно возможно с GROUP, пожалуйста, опишите и покажите мне ошибку моих способов. А пока я начну возиться с группировкой с этой целью.

Ответы [ 4 ]

0 голосов
/ 13 февраля 2020

Ниже приведен запрос, возвращающий последовательные даты между указанной датой и данной датой - 5 дней. Вы можете использовать CURRENT DATE вместо этой константы, конечно.

WITH T (DT) AS 
(
VALUES DATE('2020-02-13') - 5 DAYS
  UNION ALL
SELECT DT + 1 DAY
FROM T 
WHERE DT < DATE('2020-02-13')
)
SELECT DT FROM T;

Результат:

|DT        |
|----------|
|2020-02-08|
|2020-02-09|
|2020-02-10|
|2020-02-11|
|2020-02-12|
|2020-02-13|

Дальнейшее использование такой "виртуальной таблицы" очевидно: вы можете LEFT JOIN это с вашей базовой таблицей на B.START_DATE < DEC(TO_CHAR(T.DT, 'YYYYMMDD'), 8) AND DEC(TO_CHAR(T.DT, 'YYYYMMDD'), 8) <= B.END_DATE, сгруппировав результат по T.DT.

0 голосов
/ 12 февраля 2020

Похоже на простое использование оператора group by, но вы не указываете, по какому столбцу вы группируете, просто по дате, я приму START_DATE

Я не знаю, AS / 400 SQL поэтому я собираюсь быть немного абстрактным и предположить, что CURRENT_DATE () возвращает текущую дату в вашей локали. СУБД 'варьируются в этом отношении.

Учитывая эти предположения, должно помочь что-то вроде следующего:


SELECT
        START_DATE as DATE,
        COUNT(*) as OPEN
    FROM
        MYFILE
    WHERE 
        START_DATE >= (CURRENT_DATE() - 5)
    AND (
            END_DATE >= (CURRENT_DATE() - 5)
        OR  END_DATE = '0'
        )
    GROUP BY
        START_DATE

0 голосов
/ 12 февраля 2020

Отключить данные и объединить с оконными функциями. Вот идея:

with se as (
      select dte, sum(ins) as ins, sum(outs) as outs
      from ((select start_date as dte, count(*) as ins, 0 as outs
             from t
            ) union all
            (select end_date, 0, count(*) as outs
             from t
            )
           )
select dte, ins, outs,
       (sum(sum(ins)) over (order by dte) -
        sum(sum(outs)) over (order by dte)
       )
from se
order by dte;

Суммирует все запуски до определенного дня и вычитает количество концов.

Примечания:

  • Если Вы хотите фильтровать по дате, поместите логику фильтрации c в запрос external .
  • Предполагается, что все даты действительны. Если некоторые даты особенные, вы должны принять это во внимание в order by.
  • . Это НЕ учитывает кого-либо в день их отъезда. Если вы хотите посчитать их, просто добавьте 1 день к end_date в подзапросе.
0 голосов
/ 12 февраля 2020

Пожалуйста, попробуйте это:

SELECT COUNT(*) FROM MYFILE WHERE (START_DATE < '20200205' AND (END_DATE >= '20200210' OR END_DATE = '0')) GROUP BY DATE_FORMAT(START_DATE , '%Y%m%d')
...