2017-02-13 4 views
0

У меня есть столбцы с именем и днем, поэтому у одного и того же имени может быть несколько дат, . Каким будет запрос в oracle для извлечения данных с днем ​​предыдущего дня с определенного дня, для пример:Запрос в oracle для извлечения данных с днем ​​предыдущего времени с определенного дня

name daytime 
t12 12-Mar-2016 
t12 14-Aug-2016 
t34 13-Jan-2005 
t34 18-Mar-2005 

и мне нужно:

name daytime 
t12 12-Mar-2016 
t34 13-Jan-2005 

спасибо, S

+1

У меня искушение использовать min (date). Просьба уточнить, если это не то, что вам нужно. – GurV

+0

Я не могу использовать min (date), так как мне нужен один до определенной даты, потому что может быть «t12 11-jan-2016», но мне нужно «t12 12-Mar-2016». –

+2

Пожалуйста, добавьте дополнительные данные, чтобы очистить этот пункт. Что значит «раньше»? – GurV

ответ

0

Вы можете использовать Min A группа й по

select name, min(daytime) 
from my_table 
group by name 
0

Один из способов заключается в использовании аналитической функции row_number() (или, возможно, один из его близких родственников, либо rank() или dense_rank(), в зависимости от требований. Они будут производить одинаковый вывод, если нет «связей», то есть вы не можете иметь два ряда с одинаковыми nameи то же самое daytime).

Это чаще всего используется с rn = 1 для получения максимальной daytime; если вы хотите «второе» последнее daytime, используйте rn = 2.

Внутренний запрос возвращает одну строку для каждой строки во входной таблице - с теми же столбцами и значениями в каждой строке и столбце и с одним добавленным столбцом, rn, показывающим «ранг» каждой строки в своей группе ряды с одинаковыми name (колонка в partition by), заказанные daytimedesc завершение. Тогда должно быть очевидно, что делает внешний запрос.

with 
    test_data (name, daytime) as ( 
     select 't12', to_date('12-Mar-2016', 'dd-Mon-yyyy') from dual union all 
     select 't12', to_date('14-Aug-2016', 'dd-Mon-yyyy') from dual union all 
     select 't34', to_date('13-Jan-2005', 'dd-Mon-yyyy') from dual union all 
     select 't34', to_date('18-Mar-2005', 'dd-Mon-yyyy') from dual 
    ) 
-- End of test data (not part of the solution). SQL query begins BELOW THIS LINE 
select name, daytime 
from (
     select name, daytime, 
       row_number() over (partition by name order by daytime desc) as rn 
     from test_data 
     ) 
where rn = 2 
; 

NAME DAYTIME 
---- ----------- 
t12 12-Mar-2016 
t34 13-Jan-2005 

2 rows selected. 
0

Я не уверен, что понял вопрос, но, возможно, вы хотите использовать LAG. Это даст вам дату до любой даты, если не будет дубликатов. Заимствование данных теста Mathguy CTE, я попробовал:

with 
    test_data (name, daytime) as ( 
     select 't12', to_date('12-Mar-2016', 'dd-Mon-yyyy') from dual union all 
     select 't12', to_date('14-Aug-2016', 'dd-Mon-yyyy') from dual union all 
     select 't34', to_date('13-Jan-2005', 'dd-Mon-yyyy') from dual union all 
     select 't34', to_date('18-Mar-2005', 'dd-Mon-yyyy') from dual 
    ) 
-- End of test data (not part of the solution). SQL query begins BELOW THIS LINE 
select * from 
(
select name, lag(daytime) over(partition by name order by daytime) daytime 
from test_data 
) 
where daytime is not null