Данные SQL-запроса между датами, эффективность - PullRequest
0 голосов
/ 27 июня 2018

Я пытаюсь найти таблицу довольно большого размера (56m + строка) с помощью SQL-запроса. Сложность в том, чтобы просто выполнить быстрый SQL-запрос, подобный следующему:

Select *COLUMNS*
From *Table*
Where *Conditions* And
      LOG_ENTRY_TIMESTAMP between {StartDate} and {EndDate}

заключается в том, что мне нужно получить 23:00 - 24:00 часа по сравнению с предыдущим днем ​​{StartDate}, не извлекая оставшиеся данные с этой даты. {StartDate} и {EndDate} являются полями, введенными пользователем в формате DATE. LOG_ENTRY_TIMESTAMP является типом данных TIMESTAMP.

Есть ли более эффективный способ сделать это, чем делать что-то вроде:

TRUNC(CAST(LOG_ENTRY_TIMESTAMP AS DATE), 'HH') BETWEEN {StartDate}-1/24 and {EndDate}+23/24

Данные будут выглядеть так:

ITEM   LOG_ENTRY_TIMESTAMP
----   ----------------------------------
A      2/12/2018 10:02:19.214528 AM -0500
B      2/14/2018 11:02:19.224528 PM -0500
C      2/16/2018 01:02:19.412528 AM -0500
D      2/16/2018 11:02:19.412528 PM -0500

И если я выполню поиск от {StartDate} = 15.02.2017 до {EndDate} = 16.02.2017, я захочу захватить B & C.

Ответы [ 2 ]

0 голосов
/ 27 июня 2018

Мне нужны данные с 23 часов вечера до 23 часов вечера

, если я выполняю поиск от {StartDate} = 15.02.2017 до {EndDate} = 16.02.2017, я хочу получить B & C.

Предполагая, что LOG_ENTRY_TIMESTAMP проиндексирован, вы можете использовать это с:

Where *Conditions* And
  LOG_ENTRY_TIMESTAMP >= {StartDate} -  1/24 and
  LOG_ENTRY_TIMESTAMP <  {EndDate}   + 23/24

Опять же, предполагая, что переменные на самом деле являются датами со временем, установленным на полночь, {StartDate} - 1/24 дает вам 23:00 дня, предшествующего этой дате начала, а {EndDate} + 23/24 дает вам 23:00 дня окончания.

С вашими примерами данных в CTE и фильтром дат в виде литералов даты:

with your_table (item, log_entry_timestamp) as (
            select 'A', to_timestamp_tz('2/12/2018 10:02:19.214528 AM -0500',
              'MM/DD/YYYY HH:MI:SS.FF6 AM TZHTZM') from dual
  union all select 'B', to_timestamp_tz('2/14/2018 11:02:19.224528 PM -0500',
              'MM/DD/YYYY HH:MI:SS.FF6 AM TZHTZM') from dual
  union all select 'C', to_timestamp_tz('2/16/2018 01:02:19.412528 AM -0500',
              'MM/DD/YYYY HH:MI:SS.FF6 AM TZHTZM') from dual
  union all select 'D', to_timestamp_tz('2/16/2018 11:02:19.412528 PM -0500',
              'MM/DD/YYYY HH:MI:SS.FF6 AM TZHTZM') from dual
)
select *
from your_table
where LOG_ENTRY_TIMESTAMP >= date '2018-02-15' -  1/24
  and LOG_ENTRY_TIMESTAMP <  date '2018-02-16' + 23/24;

I LOG_ENTRY_TIMESTAMP              
- ---------------------------------
B 2018-02-14 23:02:19.224528 -05:00
C 2018-02-16 01:02:19.412528 -05:00

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

0 голосов
/ 27 июня 2018

Я бы предложил:

Where *Conditions* And
      LOG_ENTRY_TIMESTAMP between {StartDate} - 1/24 and {EndDate}
...