2016-04-18 11 views
0

テーブルクローゼットの最後のエントリを定義した日付にフィルタリングしようとしていますが、問題があります。どんな入力も大歓迎です。ありがとう!私はMicrosoft SQL Server 2008SQL最後のエントリを日付に最後に検索

表を実行しています:

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 

私は3月31日( '2016年3月31日')に最も近い日付のエントリのみを選択します。この例では、アカウント1234の2016-03-31に最も近いエントリはエントリ3であり、アカウント7890の2016-03-31に最も近いエントリはエントリ5です。言い換えれば、私はすべての勘定科目の最後の記入項目を日付と同じにしたい。

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

最も近い定義します。なぜそれは3を示すのですか? 1234 | | 2016-03-05 | 842 and not 2 | 1234 | | 2016-03-01 | 650 –

+0

は、あまりにもあまりにもコード化するのが曖昧です。どういう意味ですか?日付の前に最も近い単一のレコード?前または後に提供された日付に最も近いか?あなたは1-2の記録を期待していますか? SQLのどんな風味ですか? mySQL、SQL Server、oracle、SyBaseなど... – xQbert

+1

どのDBMSを使用していますか? Postgres?オラクル? DB2? –

答えて

1

ほとんどのDBMSは:

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 

編集:SQL Server用には、分析を使用する方がよいかもしれません関数(row_numberなど)

0

DBMSが指定されていないので、ここではSQL Serverでこれを行うためのハック方法です。それはちょうど前とだけ指定した日付の後のレコードをつかむ:分析機能をサポート(MS 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