我在写下面的SQL查询时遇到困难。 我有一张桌子:
id | C1 | C2 | date
1 | 1 | 1 | 1/10/2010 9:30:10
2 | 1 | 1 | 1/10/2010 9:31:10
3 | 1 | 1 | 1/10/2010 9:32:10
4 | 1 | 1 | 1/10/2010 9:37:10
5 | 1 | 2 | 1/10/2010 9:38:10
6 | 2 | 3 | 1/10/2010 9:39:10
7 | 2 | 3 | 1/10/2010 9:45:10
8 | 2 | 3 | 1/10/2010 9:46:10
现在我想获取如下记录:
按日期差异(最新日期)分组记录5分钟,同一C1和同一C2
(即记录如同相同C1的每个C2的5分钟内的latset日期)
我只想输出:
id | C1 | C2 | date
3 | 1 | 1 | 1/10/2010 9:32:10
4 | 1 | 1 | 1/10/2010 9:37:10
5 | 1 | 2 | 1/10/2010 9:38:10
6 | 2 | 3 | 1/10/2010 9:39:10
7 | 2 | 3 | 1/10/2010 9:46:10
说明:
1.前3条记录分组(同一C1和5分钟内相同的C2)和第3条记录(最新的3条记录)。
2. 4记录取。 (它是向后5分钟内的唯一记录,同一C1和同一C2的前5分钟)
3.与上述相同
同样高达......第8记录
我尝试了各种分组和查询分区,但被卡住了。任何帮助,将不胜感激。谢谢
答案 0 :(得分:2)
可能有一个更简单的解决方案,但我使用了一个公用表表达式checktimesagainsttimes
来检查针对同一个表连接的一个记录的前进和后退。如果我的数据位于名为test3的表中,则将数据视为表m2,将其作为表m1连接到其自身以及作为表m3之后的记录。
它会比较m1,m2和m3中的日期,并返回一个列checktimesagainsttimes
的表WithinFiveMinutes
,如果它在前一个或下一个记录的五分钟内,则返回1。
然后我使用另一个公用表表达式来查询checktimesagainsttimes
两次。我第一次获得他们在五分钟内的组的最长日期。然后我将结果与checktimesagainsttimes
的结果联合起来,这些结果彼此不在五分钟之内。这些结果将在5分钟内恢复到最大值。
最后要做的是获取这些结果,并根据c1,c2和日期返回原始表格,以取回实际的rowed
。
WITH checktimesagainsttimes
AS ( SELECT m2.id AS id2 ,
m1.id AS id1 ,
m3.id AS id3 ,
m2.date ,
m2.c1 ,
m2.c2 ,
CASE WHEN ( DATEADD(mi, 5, m2.date) > m3.date
AND m2.date < m3.date
)
OR ( DATEADD(mi, -5, m2.date) < m1.date
AND m2.date > m1.date
) THEN 1
ELSE 0
END AS WithinFiveMinutes
FROM test3 m2
LEFT OUTER JOIN test3 m1 ON m2.c1 = m1.c1
AND m2.c2 = m1.c2
AND ( m2.id = m1.id
+ 1 )
LEFT OUTER JOIN test3 m3 ON m2.c1 = m3.c1
AND m2.c2 = m3.c2
AND ( m2.id = m3.id
- 1 )
),
maxdatesforwithin5minutes
AS ( SELECT c1 ,
c2 ,
MAX(date) AS date
FROM checktimesagainsttimes
WHERE WithinFiveMinutes = 1
GROUP BY c1 ,
c2 ,
withinFiveMinutes
UNION
SELECT c1 ,
c2 ,
date
FROM checktimesagainsttimes
WHERE WithinFiveMinutes = 0
)
SELECT t.id ,
t.c1 ,
t.c2 ,
t.date
FROM maxdatesforwithin5minutes m
INNER JOIN test3 t ON m.c1 = t.c1
AND m.c2 = t.c2
AND m.date = t.date
答案 1 :(得分:1)
尝试
SELECT MAX(id), C1, C2, MAX([date])
FROM tbl
GROUP BY C1, C2, DATEADD(MINUTE, DATEDIFF(MINUTE,0,[date]) / 5 * 5, 0)