3

より古い最新のvalueperを見つけようとしていますid1/1/2013

create table #foo
(
    id int,
    value money,
    entry_date datetime
)

insert into #foo values (1, 1.00, '1/1/2012')
insert into #foo values (1, 2.00, '2/1/2012')
insert into #foo values (1, 7.00, '1/1/2013')
insert into #foo values (2, 1.00, '1/1/2013')
insert into #foo values (2, 1.00, '2/1/2013')
insert into #foo values (3, 5.00, '3/1/2012')

以下に解決策を示しますが、これを間違った方法で行っていることはわかっています。

select id, value
from
(
    select id, value, row_number() over (partition by id order by entry_date desc) as ind
    from #foo
    where entry_date < '1/1/2013'
) a where ind = 1

--Results:
--id          value
------------- ---------------------
--1           2.00
--3           5.00

2013 年 1 月 1 日より古いレコードがないため、ID 2 は返されません。

私がやろうとしていることを達成する正しい方法は何ですか?

4

4 に答える 4

6

サブクエリを使用して結果を取得することもできます。

select f1.id, f1.value
from #foo f1
inner join
(
  select id, max(entry_date) entry_date
  from #foo
  where entry_date < '1/1/2013'
  group by id
) f2
  on f1.id = f2.id
  and f1.entry_date = f2.entry_date;

デモで SQL Fiddle を参照してください

于 2013-05-07T16:27:03.410 に答える
2

これは同じ方針ですが、サブクエリの必要性をなくすためにaTOP 1 WITH TIESと組み合わせて使用​​することもできます:ROW_NUMBER()

select top 1 with ties id, value
from #foo
where entry_date < '1/1/2013'
order by row_number() over (partition by id order by entry_date desc)

私の意見では、それは少しきれいです。残念ながら、パフォーマンスがわずかに遅くなる可能性もあります。それでも、SQL 関数のさまざまな用途を知っておくことは常に有益です。

于 2013-05-07T16:29:33.163 に答える
1

EXISTS演算子でオプションを使用する

SELECT t.id, t.value
FROM #foo t
WHERE t.entry_date < '1/1/2013'
 AND EXISTS(
            SELECT 1
            FROM #foo t2
            WHERE t.id = t2.id
              AND t2.entry_date < '1/1/2013'
            HAVING MAX(t2.entry_date) = t.entry_date
            )

SQLFiddle のデモ

パフォーマンスを改善するには、次のインデックスを使用します。

CREATE INDEX x ON #foo(id, entry_date) INCLUDE(value)
于 2013-05-07T16:26:24.257 に答える
1

ランキング関数とSQL-Server 2005共通テーブル式 (CTE) があります。

WITH CTE AS
(
   SELECT id,value,entry_date,
          RN = ROW_NUMBER() OVER (PARTITION BY id ORDER BY entry_date DESC)
   FROM dbo.TableName
   WHERE entry_date < '1/1/2013'
)
SELECT id,value,entry_date FROM CTE WHERE RN = 1

ID ごとに最新のレコードを返すためORDER BY entry_date DESCvalue.

複数ある場合にすべての「max-recent」値が必要な場合は、に置き換えROW_NUMBERますDENSE_RANK

于 2013-05-07T16:21:17.823 に答える