2016-04-18 4 views
0

Я пытаюсь отфильтровать последнюю запись в шкафу таблицы до определенной даты, и у меня возникают трудности. Любой вход очень приветствуется. Благодаря! Я бегу Microsoft SQL Server 2008.SQL Найти последнюю запись Ближайшие к дате

Таблица:

code | account | date   | amount 
1 | 1234 | 2016-02-28  | 500 
2 | 1234 | 2016-03-01  | 650 
3 | 1234 | 2016-03-05  | 842 
4 | 7890 | 2016-02-28  | 500 
5 | 7890 | 2016-03-30  | 550 

Я хочу, чтобы выбрать только записи с датой ближе к 31 марта ('2016-03-31'). В этом примере запись, ближайшая к 2016-03-31 для учетной записи 1234, - это запись № 3, а запись, ближайшая к 2016-03-31 для учетной записи 7890, - это запись №5. Другими словами, я хочу, чтобы последняя запись для всех учетных записей была равна или до даты.

3 | 1234 | 2016-03-05  | 842 
5 | 7890 | 2016-03-30  | 550 
+1

Определить ближе. Почему это показывает 3 | 1234 | 2016-03-05 | 842, а не 2 | 1234 | 2016-03-01 | 650 –

+0

ближайший слишком расплывчатый код. Что вы имеете в виду? ближайшая одиночная запись, предшествующая дате? или ближе к дате, указанной до или после? вы ожидаете 1-2 записи? и какой вкус/verson SQL? mySQL, SQL Server, oracle, SyBase и т. д. – xQbert

+1

Какая СУБД вы используете? Postgres? Oracle? DB2? –

ответ

1

Большинство DBMSes (включая MS SQL Server) поддерживает аналитические функции:

select * 
from 
(
    select *, 
     row_number()     -- create a ranking 
     over (partition by account  -- for each account 
      order by date desc) as rn -- based on descending dates 
    from tab 
    where date <= date '2016-03-31' 
) dt 
where rn = 1       -- return the row with the "closest" date 
+0

Работает отлично! Благодаря! – spiderlily

0

Это должно делать то, что вы хотите, и она должна быть достаточно легко понять, чтобы не нужно дальнейшее объяснение:

select t.* 
from your_table t 
join (
    select account, max(date) as date 
    from your_table 
    where date <= '2016-03-31' 
    group by account 
) as subquery on t.account = subquery.account and t.date = subquery.date 

Edit: для SQL Server может быть лучше использовать аналитический function (например, row_number)

0

Поскольку спецификация DBMS не указана, вот что-то вроде хакерского способа сделать это в SQL Server. Она захватывает запись непосредственно перед и сразу после указанной даты:

select * from (
    select top(1) * FROM mytable 
    where date >= '2016-03-31' order by date asc 
) t1 
union 
select * from (
    select top(1) * FROM mytable 
    where date <= '2016-03-31' order by date desc 
) t2 
Смежные вопросы