Подсчет количества строк в столбце по сравнению с системной датой ORACLE - PullRequest
1 голос
/ 12 октября 2019

У меня есть таблица со столбцом due_date, который определяет, когда должен быть инструмент. Мне нужно сравнить это значение с системной датой (sysdate) и посчитать, сколько строк заполняют определенные условия.

Мне нужно:

Подсчитать количество строк с помощью инструментов, которые являются DUE (due_date> sysdate) ex- "tools_due" с 50 строками

Подсчитать количество строкинструментов, которые НЕ DUE (due_date

и

Подсчитать количество строк, которые DUE TODAY (due_date = sysdate) ex- "tools_today"с 10 строками

ТО мне нужно взять каждый счет, сравнить и сохранить условие с наибольшим количеством строк. ex- "lower_count"

Таким образом, в этом примере tools_due возвратился с 50 строками, что является наибольшим из 3, поэтому значение high_count будет равно 50 или "tools_due".

Как бы я мог это сделать? Я пытался использовать регистр внутри пунктов count, но я уверен, что я не использую его правильно.

EDIT - забыл упомянуть, что мой вывод должен выдавать хотя бы одну из строк, которые я вставил в эти строки. Строки СУБД на скриншоте. Мой плохой мой плохой.

Вот что у меня есть: мой код doodoo

Ответы [ 5 ]

0 голосов
/ 13 октября 2019

Использование TRUNC( due_date ) не позволит Oracle использовать индекс для столбца due_date (вместо этого вам потребуется индекс на основе функции). Альтернативой будет:

SELECT COUNT(
         CASE
         WHEN due_date >= TRUNC( SYSDATE ) + INTERVAL '1' DAY
         THEN due_date
         END
       ) AS tools_not_due_yet,
       COUNT(
         CASE
         WHEN due_date >= TRUNC( SYSDATE )
         AND  due_date <  TRUNC( SYSDATE ) + INTERVAL '1' DAY
         THEN due_date
         END
       ) AS tools_due_today,
       COUNT(
         CASE
         WHEN due_date <  TRUNC( SYSDATE )
         THEN due_date
         END
       ) AS tools_overdue
FROM   your_table
0 голосов
/ 13 октября 2019

Вы можете использовать group by следующим образом:

Select max(count(1)) from
(Select case when diff = 0 
             then 'due today'
             When diff < 0 then 'due'
             Else 'not due' end as status
 From
(Select trunc(due_date) - trunc(sysdate) as diff,
        Due_date 
  from your table))
Group by status;

Ура !!

0 голосов
/ 13 октября 2019

Чтобы отобразить регистр (не из-за, из-за-сегодня), который имеет наибольшее количество, проще обрабатывать строки, чем столбцы. Вы можете использовать UNION ALL для генерации записей для каждого из трех случаев, а затем упорядочивать строки по количеству и возвращать только записи с наибольшим количеством:

SELECT *
FROM (
    SELECT *
    FROM (
        SELECT 'due' reason, COUNT(*) cnt FROM mytable WHERE TRUNC(due_date) > TRUNC(sysdate)
        UNION ALL SELECT 'not due', COUNT(*) FROM mytable WHERE TRUNC(due_date) < TRUNC(sysdate)
        UNION ALL SELECT 'due today', COUNT(*) FROM mytable WHERE TRUNC(due_date) = TRUNC(sysdate)
    ) 
    ORDER BY cnt DESC
)
WHERE ROWNUM = 1

Демонстрация в БДСкрипка

Настройка:

| DUE_DATE            |
| :------------------ |
| 2019-10-10 22:10:43 |
| 2019-10-11 22:10:43 |
| 2019-10-12 22:10:43 |
| 2019-10-13 22:10:43 |

Результаты:

REASON  | CNT
:------ | --:
not due |   2
0 голосов
/ 13 октября 2019

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

    Trunc(column) = trunc(sysdate) 
0 голосов
/ 13 октября 2019

Я думаю, вам нужна логика, подобная этой:

select sum(case when trunc(due_date) > trunc(sysdate + 1) then 1 else  0 end) as due_later,
       sum(case when trunc(due_date) = trunc(sysdate) then 1 else 0 end) as due_today,
       sum(case when trunc(due_date) < trunc(sysdate) then 1 else 0 end) as due_earlier
from . . .

В Oracle sysdate имеет компонент времени, и это может вас отбросить. Кроме того, тип данных date имеет компонент времени, который вы можете не увидеть при просмотре значения.

...