Интервал SQL с подзапросами

#sql #oracle #datetime #subquery #intervals

#sql #Oracle #дата-время #подзапрос #интервалы

Вопрос:

Я хочу отфильтровать старые записи на определенную дату, и этот SQL не работает:

 SELECT * 
FROM TABLE1 
WHERE UPDATED_ON   INTERVAL (SELECT B.DAYS FROM B.TABLE2 
                             WHERE B.NAME = 'Tmp') DAY < SYSDATE;
  

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

 SELECT * 
FROM TABLE1 
WHERE UPDATED_ON   INTERVAL '2' DAY < SYSDATE;
  

Комментарии:

1. Вы используете MS SQL Server или Oracle? Их функции даты / времени сильно отличаются.

2. Я использую oracle

Ответ №1:

Либо используйте

 WHERE
   UPDATED_ON 
        (SELECT B.DAYS FROM B.TABLE2 WHERE B.NAME = 'Tmp') * INTERVAL '1' DAY < SYSTIMESTAMP
  

или

 WHERE
   UPDATED_ON 
        NUMTODSINTERVAL((SELECT B.DAYS FROM B.TABLE2 WHERE B.NAME = 'Tmp'), 'day') < SYSTIMESTAMP
  

или

 WHERE
   UPDATED_ON 
        (SELECT B.DAYS FROM B.TABLE2 WHERE B.NAME = 'Tmp') < SYSDATE
  

Комментарии:

1. Это отличный взлом. Я создал новую мета-таблицу, где я обновляю этот номер. количество дней в нем. Я использую это как подзапрос и умножаю с интервалом. Работает как шарм

Ответ №2:

Вы можете попробовать это вот так:

 select UPDATED_ON
       , UPDATED_ON     (SELECT t2.DAYS FROM TABLE2 t2 WHERE t2.NAME = 'Tmp') 
FROM TABLE1 
WHERE UPDATED_ON    (SELECT t2.DAYS FROM TABLE2 t2 WHERE t2.NAME = 'Tmp')  < SYSDATE;
  

Вот демонстрационный:

ДЕМОНСТРАЦИЯ

Ответ №3:

Вы могли бы записать это как:

 select t1.*
from table1 t1
where updated_on < (
    select systimestamp - t2.days * interval '1' day from table2 t2 where t2.name = 'Tmp'
)
  

В качестве альтернативы, если updated_on — это date ,а не timestamp :

 select t1.*
from table1 t1
where updated_on < (
    select sysdate - t2.days from table2 t2 where t2.name = 'Tmp'
)
  

Обратите внимание, что это приведет к сбою, если есть более одной строки, в table2 которой name есть 'Tmp' .

Комментарии:

1. Да, у меня более одной строки в таблице2

2. Я предпочитаю не смешивать DATE и INTERVAL типы. Либо используйте числа TIMESTAMP (т. Е. SYSTIMESTAMP ) и INTERVAL или DATE и (т.е. количество дней). Вы можете смешивать их, но если вы не знакомы с неявными преобразованиями, то результат может быть не таким, как ожидалось.

3. @WernfriedDomscheit: спасибо, это хороший момент. Я обновил свой ответ.