Не возвращайте данные за последние 5 дней, если не задано значение в предложении WHERE - PullRequest
0 голосов
/ 25 октября 2019

Это упрощенная версия, но я пытаюсь создать представление, которое возвращает данные за последние 5 дней (включая сегодняшний день):

select distinct data_dt
from(
     select *
        from table1 t
       WHERE t.data_dt BETWEEN specified_dt - 4 and specified_dt
     )
where specified_dt = date'2019-05-01';

Возвращает только данные за текущий день.

Когда я ввожу жестко закодированную дату в предложении WHERE (как показано ниже), я возвращаю правильный набор данных. Однако, когда я переключаю жестко закодированную дату с параметром, которому я присваиваю значение во внешнем запросе (как показано в запросе выше), он возвращает только указанную дату в предложении where (но не последние 4 дня).

select distinct data_dt
  from table1 t
 WHERE t.data_dt BETWEEN date'2019-05-01'- 4 and date'2019-05-01';

Я что-то забыл?

Заранее спасибо.

Ответы [ 4 ]

1 голос
/ 26 октября 2019

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

Пример таблицы с данными до и после искомого окна

create table t (
  col1 integer,
  date_dt date 
);

insert into t values( 1, date '2019-04-01' );
insert into t values( 2, date '2019-04-10' );
insert into t values( 3, date '2019-04-20' );
insert into t values( 4, date '2019-04-27' );
insert into t values( 5, date '2019-04-28' );
insert into t values( 6, date '2019-04-29' );
insert into t values( 7, date '2019-04-30' );
insert into t values( 8, date '2019-05-01' );
insert into t values( 9, date '2019-05-02' );

Вам понадобится тип объекта, коллекция и табличная функция.

create type t_obj as object (
  col1 integer,
  date_dt date
);
/

create type tbl_obj as table of t_obj;
/

create or replace function last_5_days( p_date_dt in date )
  return tbl_obj
  pipelined
is
begin
  for i in (select * from t where date_dt between p_date_dt - 4 and p_date_dt )
  loop
    pipe row( t_obj( i.col1, i.date_dt ) );
  end loop;
  return;
end;
/

Теперь вы можете запросить табличную функцию, передать дату и получить 5 строк назад (27 апреля - 1 мая)

select *
  from last_5_days( date '2019-05-01' );

Пример выполнения этого на liveSQL

1 голос
/ 25 октября 2019

Ваше мнение (внутренний запрос в вашем вопросе) не должно иметь никаких условий даты. Все условия должны быть в внешнем WHERE предложении.

Что-то вроде следующего:

select distinct data_dt
from(
     select *
        from table1 t
       WHERE <other conditions> -- removed between condition from here
     )
where data_dt = between specified_dt - 4 and specified_dt; -- condition here

- обновление -

Вы можетеиспользуйте connect by level, чтобы сгенерировать всего 5 строк из 1 строки, а затем сравнить ее с вашей датой следующим образом:

select distinct data_dt -- changed this, try now
from(
     select t.*, t.data_dt - days.lvl + 1 as data_dt_5days
        from table1 t
        Cross Join (select level as lvl from dual connect by level <= 5) days
       WHERE <other_conditions>
     )
where data_dt_5days = date'2019-05-01';

Cheers !!

1 голос
/ 25 октября 2019

Если вы действительно создаете представление, вам может подойти что-то вроде этого:

CREATE OR REPLACE VIEW table_view AS
  SELECT t.data_dt+5 AS MAX_DATE, t.*
  FROM table1 t
  WHERE <OTHER_CONDITIONS>;

После создания представления вы можете просто сделать выбор, подобный этому:

SELECT *
FROM table_view tv
WHERE to_date('01/01/2020', 'MM/DD/YYYY') BETWEEN tv.data_dt AND tv.max_date; --Or whatever date you needed
1 голос
/ 25 октября 2019

Что значит "назначить параметр во внешнем запросе"? Это не имеет смысла. Если вы хотите это как «параметр», вы можете использовать cross join:

select distinct data_dt
from table1 t cross join
     (select date '2019-05-01' as specified_dt from dual) params
where t.data_dt between specified_dt - 4 and specified_dt;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...