我有一个表(SQL Server 2005),其中包含以下列:
State:
- StateId INT PRIMARY KEY
- VehicleId INT
- ValidFromDate DATETIME
对于每个VehicleId
,此表中可以有多行。我想选择当前有效的状态(带有日期参数)。每辆车最多可以有一个有效状态(最小ValidFromDate
小于日期参数的车辆。)
如果表格如下:
StateId VehicleId ValidFromDate
--- --- ---
1 1 2009-01-01
2 1 2009-06-02
3 1 2009-11-03
4 2 2009-06-04
5 3 2009-10-05
@Date = '2009-08-14'
我希望查询产生以下结果:
StateId VehicleId ValidFromDate
--- --- ---
2 1 2009-06-02
4 2 2009-06-04
我认为以下查询会产生正确的结果:
SELECT * FROM State s1
WHERE s1.StateId IN (SELECT TOP 1 StateId
FROM State s2
WHERE s2.ValidFromDate <= @Date AND s1.VehicleId = s2.VehicleId
ORDER BY s2.ValidFromDate DESC, s2.StateId DESC)
但是必须有一种更好的方法来做到这一点,使用某种分组条款,对吧?使用同一个表的子查询感觉不对。
答案 0 :(得分:1)
使用TOP 1的方式只返回一行,而不是所有可能的行。我相信你正在寻找的结果是这样的。
但它仍然使用子查询来获取MAX日期。我现在知道另一种方式。但是,我经常使用它,虽然速度不快,但我发现它并不太慢。
SELECT
*
FROM
State
WHERE
State.ValidFromDate =
(
SELECT
MAX(ValidDromDate)
FROM
State2
WHERE
State2.VehicleId = State.VehicleId
AND
State2.ValidFromDate <= @Date
)
答案 1 :(得分:1)
您可以使用SQL 2005 RANK子句来帮助解决“按组排名前X”问题。
这样的查询可以解决您的问题。注意:我认为在给定数据的情况下,VehicleId应该是您预期结果集中的2。
SELECT dateranks.*
FROM
(
select
s1.StateId,
s1.VehicleId,
s1.ValidFromDate,
RANK() OVER (PARTITION BY s1.VehicleId ORDER BY s1.ValidFromDate desc) AS 'DateRank'
FROM [state] s1
WHERE
ValidFromDate <= '8/14/2009'
)
dateranks
where
dateranks.ValidFromDate <= '8/14/2009'
AND DateRank = 1
有用的链接: