1

我们有具有以下数据和结构的表 T

__________________________
ID  |  Grp   |     Dt     |
____|________|____________|
1   |   A    |  2007-11-22|  
2   |   A    |  2008-01-03|  
3   |   A    |  2008-01-03|  
4   |   A    |  2011-04-13|  
5   |   B    |  2007-11-22|  
6   |   B    |  2010-04-28|  
7   |   B    |  2009-03-19|  
8   |   B    |  2007-11-22|  
9   |   C    |  2010-04-28|  
10  |   C    |  2009-03-19|  
11  |   C    |  2011-04-13|  
12  |   C    |  2012-02-22|  
13  |   D    |  2007-11-22|  
14  |   D    |  2010-04-28|  
15  |   D    |  2009-03-19|  
16  |   E    |  2007-11-22|  
17  |   E    |  2010-04-28|  
18  |   E    |  2011-04-13|  
19  |   F    |  2007-11-22|  
20  |   G    |  2007-11-22|  
21  |   H    |  2007-11-22|  
22  |   H    |  2010-04-28|  
23  |   H    |  2009-03-19|  
24  |   H    |  2008-03-15|
____|________|____________|

给定@date_from = '2007-01-01'@date_to = '2008-06-01' 编写一个查询,该查询返回 @date_from 到 @date_to 的过滤子集的最大记录。

结果应如下所示:

__________________________
ID  |  Grp   |     Dt     |
____|________|____________|
2   |   A    |  2008-01-03|  
3   |   A    |  2008-01-03|  
5   |   B    |  2007-11-22|  
8   |   B    |  2007-11-22|  
13  |   D    |  2007-11-22|  
16  |   E    |  2007-11-22|  
19  |   F    |  2007-11-22|  
20  |   G    |  2007-11-22|  
21  |   H    |  2008-03-05|  
____|________|____________|

一种可能的解决方案是:

DECLARE @date_from AS DATE = '2007-01-01'
DECLARE @date_to   AS DATE = '2008-06-01'

WITH TFltr AS ( SELECT ID, Grp, Dt FROM T WHERE @date_from <= Dt AND Dt <= @date_to )
SELECT t1.ID, t1.Grp, t1.Dt 
FROM TFltr t1
LEFT OUTER JOIN TFltr t2 ON t1.Grp = t2.Grp AND t1.Dt < t2.Dt
WHERE t2.ID IS NULL

所以你知道一个更好/更快的方法来做到这一点。

谢谢。

4

4 回答 4

1

另一种解决方案:

SQLFIDDLE示例

SELECT t.*
FROM TFltr t
WHERE t.Dt >='2007-01-01'
AND t.Dt <= '2008-06-01'
AND t.Dt = (SELECT MAX(h.Dt)
            FROM TFltr h
            WHERE h.Dt >='2007-01-01'
            AND h.Dt <= '2008-06-01' 
            AND h.Grp = t.Grp)
ORDER BY t.ID

结果:

| ID | GRP |                              DT |
----------------------------------------------
|  2 |   A |  January, 03 2008 00:00:00+0000 |
|  3 |   A |  January, 03 2008 00:00:00+0000 |
|  5 |   B | November, 22 2007 00:00:00+0000 |
|  8 |   B | November, 22 2007 00:00:00+0000 |
| 13 |   D | November, 22 2007 00:00:00+0000 |
| 16 |   E | November, 22 2007 00:00:00+0000 |
| 19 |   F | November, 22 2007 00:00:00+0000 |
| 20 |   G | November, 22 2007 00:00:00+0000 |
| 24 |   H |    March, 15 2008 00:00:00+0000 |

您的查询:

DECLARE @date_from AS DATE = '2007-01-01'
DECLARE @date_to   AS DATE = '2008-06-01'

SELECT t.*
FROM TFltr t
WHERE t.Dt >=@date_from
AND t.Dt <= @date_to
AND t.Dt = (SELECT MAX(h.Dt)
            FROM TFltr h
            WHERE h.Dt >=@date_from
            AND h.Dt <= @date_to 
            AND h.Grp = t.Grp)
ORDER BY t.ID
于 2013-03-22T09:39:38.550 回答
1

我推荐 RANK 分析函数:

DECLARE @date_from AS DATE = '2007-01-01'
DECLARE @date_to   AS DATE = '2008-06-01'

SELECT * FROM (
  SELECT ID, Grp, Dt,
    RANK() OVER (PARTITION BY Grp ORDER BY Dt DESC) AS DateRank
  FROM T
  WHERE Dt BETWEEN  @date_from AND @date_to) InnerT
WHERE DateRank = 1

内部查询将每个 中的日期从高到低排列Grp。最高日期的 aDateRank为 1。然后,外部查询仅包含DateRank = 1. 我对您帖子中的数据尝试了此查询,并得到了您想要的结果。

于 2013-03-21T16:48:19.993 回答
1
select ID, Grp, Dt
from TFltr
where dt between @date_from  and @date_to
group by ID, Grp, Dt
having dt=max(dt)

我将上面的查询更改为:

从 T 中选择 ID 作为 dt、Grp、Dt,其中 @date_from 和 @date_to 之间的 dt 按 ID、Grp、Dt 分组,其中 dt=max(dt) 和 ID=max(ID)

我得到了“更好”的结果,但它还不正确。

于 2013-03-21T16:02:01.273 回答
1
select T1.*
from T T1
inner join
(
select max(dt) as max_dt, Grp
from T
where @date_from <= dt and dt <= @date_to
group by Grp
) X
on T1.Grp = X.Grp and T1.dt = X.max_dt
于 2013-03-21T15:47:49.330 回答