3

我正在尝试value查找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与 the 结合使用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

有了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 DESC而不是value.

如果您想要所有“最大最近”值以防有多个,请替换ROW_NUMBERDENSE_RANK.

于 2013-05-07T16:21:17.823 回答
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 回答