Intereting Posts

Получать подсчет последовательных дней, соответствующих заданным критериям

У меня есть следующая структура в моей базе данных Oracle:

Date Allocation id 2015-01-01 Same 200 2015-01-02 Good 200 2015-01-03 Same 200 2015-01-04 Same 200 2015-01-05 Same 200 2015-01-06 Good 200 

Я хотел бы иметь запрос, который должен проверять только предыдущие последовательные дни и получать счетчик, где Allocation "Same" .

Я хочу выбрать по дате, например 2015-01-05 .
Пример вывода: для даты 2015-01-05 счетчик равен 3 .

Новая проблема. С запросом от Lukas Eder счет всегда 1 или 2 . но ожидается 3 . Зачем?!

 Date Allocation id 2015-01-01 Same 400 2015-01-02 Good 400 2015-01-03 Same 400 2015-01-04 Same 400 2015-01-05 Same 400 2015-01-06 Good 400 

Код от Lukas Eder

  SELECT c FROM ( SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c FROM ( SELECT allocation, d, d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part FROM t ) ) WHERE d = DATE '2015-01-05'; 

Ожидаемый результат выглядит примерно так: First_day end Последний день не нужен:

 id count first_day Last_Day 200 3 2015-01-03 2015-01-05 400 3 2015-01-03 2015-01-05 

Этот запрос даст счетчики для каждой строки:

 SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c FROM ( SELECT allocation, d, d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part FROM t ) ORDER BY d; 

Затем вы можете отфильтровать его, чтобы найти подсчеты для данной строки:

 SELECT c FROM ( SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c FROM ( SELECT allocation, d, d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part FROM t ) ) WHERE d = DATE '2015-01-05'; 

Объяснение:

Полученная таблица используется для вычисления различных разделов «разделов» для каждой даты и распределения:

  SELECT allocation, d, d - row_number() OVER (PARTITION BY allocation ORDER BY d) AS part FROM t 

Результат:

 allocation d part -------------------------------- Same 01.01.15 31.12.14 Good 02.01.15 01.01.15 Same 03.01.15 01.01.15 Same 04.01.15 01.01.15 Same 05.01.15 01.01.15 Good 06.01.15 04.01.15 

Конкретная дата, подготовленная по part имеет значения. Это будет только одна дата, которая будет одинаковой для каждой «группы» дат в пределах распределения. Затем вы можете подсчитать количество идентичных значений (allocation, part) используя функцию окна count(*) over(...) :

 SELECT allocation, d, count(*) OVER (PARTITION BY allocation, part ORDER BY d) AS c FROM (...) ORDER BY d; 

для получения желаемого результата.

Данные

Я использовал следующую таблицу для примера:

 CREATE TABLE t AS ( SELECT DATE '2015-01-01' AS d, 'Same' AS allocation FROM dual UNION ALL SELECT DATE '2015-01-02' AS d, 'Good' AS allocation FROM dual UNION ALL SELECT DATE '2015-01-03' AS d, 'Same' AS allocation FROM dual UNION ALL SELECT DATE '2015-01-04' AS d, 'Same' AS allocation FROM dual UNION ALL SELECT DATE '2015-01-05' AS d, 'Same' AS allocation FROM dual UNION ALL SELECT DATE '2015-01-06' AS d, 'Good' AS allocation FROM dual ); 

Для решения вашей проблемы рассмотрите следующий запрос:

 SELECT COUNT(*) AS `count` FROM test t WHERE `date` < '2015-01-05' AND allocation = 'Same'; 

Предположим, что данная дата – «2015-01-05». Идея здесь состоит в том, чтобы выбрать все даты, которые меньше, чем «2015-01-05», что означает его предыдущие дни. Поскольку распределение должно быть «одинаковым», поэтому оно также включено в раздел условия оператора.

Попробуй это :

 SELECT count(Allocation) as total_allocation FROM table_name WHERE (Date BETWEEN CURDATE() - INTERVAL 1 DAY AND CURDATE()) AND (Allocation='Same'); 

Это будет извлекать все записи с даты до сегодняшней даты и чье распределение = «одинаковое»,

Это легче:

DEMO

 SELECT count(*) AS c FROM t WHERE d < TO_DATE ( '2015-01-05' ,'yyyy-mm-dd' ) AND allocation = 'Same';