我需要SELECT
表格中的所有行,其中所选行的行数大于先前所选行的日期时间给定的固定分钟数。一个例子可能说得最好。
以下代表数据表 - 我们将其称为myTable。
guid fkGuid myDate
------- ------- ---------------------
1 100 2013-01-10 11:00:00.0
2 100 2013-01-10 11:05:00.0
3 100 2013-01-10 11:10:00.0
4 100 2013-01-10 11:15:00.0
5 100 2013-01-10 11:20:00.0
6 100 2013-01-10 11:25:00.0
7 100 2013-01-10 11:30:00.0
8 100 2013-01-10 11:35:00.0
9 100 2013-01-10 11:40:00.0
10 100 2013-01-10 11:50:00.0
11 100 2013-01-10 11:55:00.0
我想要做的是提供一个恒定的增量(比如说10分钟),并从前一行中获取10分钟或更长时间内的所有行。因此,在10分钟后,结果集应如下所示:
guid myDate
------- ---------------------
1 2013-01-10 11:00:00.0
3 2013-01-10 11:10:00.0
5 2013-01-10 11:20:00.0
7 2013-01-10 11:30:00.0
9 2013-01-10 11:40:00.0
11 2013-01-10 11:55:00.0
常量作为变量传入,因此它可以是任何东西。假设它是23分钟,那么结果集应如下所示:
guid myDate
------- ---------------------
1 2013-01-10 11:00:00.0
6 2013-01-10 11:25:00.0
10 2013-01-10 11:50:00.0
最后一个示例显示我从第0行的时间(11:00:00)开始添加23分钟并获得下一个> =行,即11:25:00,将新行的时间加上23分钟,然后得到下一个(11:50:00)等等。
我已经尝试过用CTE做这个但是虽然我可以很容易地回到我所有的时间或者没有一个,我似乎无法弄清楚如何获得我需要的行。我当前的测试代码使用23分钟硬编码到WHERE子句中:
WITH myCTE AS
(
SELECT guid,
myDate,
ROW_NUMBER() OVER (PARTITION BY guid ORDER BY myDate ASC) AS rowNum
FROM myTable
WHERE fkGuid = 100
)
SELECT currentRow.guid, currentRow.myDate
FROM myCTE AS currentRow
LEFT OUTER JOIN
myCTE AS previousRow
ON currentRow.guid = previousRow.guid
AND currentRow.rowNum = previousRow.rowNum + 1
WHERE
currentRow.myDate > DATEADD(minute, 23, previousRow.myDate)
ORDER BY
currentRow.myDate ASC
这不会返回任何内容。如果我省略WHERE
子句,我会收到所有行(显然是因为我没有过滤)。
我错过了什么?
任何和所有的帮助都会非常感激,因为它始终是!
答案 0 :(得分:1)
@ gilly3,几乎没有SQL voodoo
WITH CTE
AS
(
SELECT TOP 1
guid
,fkGuid
,myDate
,ROW_NUMBER() OVER (ORDER BY myDate) RowNum
FROM MyTable
UNION ALL
SELECT mt.guid
,mt.fkGuid
,mt.myDate
,ROW_NUMBER() OVER (ORDER BY mt.myDate)
FROM MyTable mt
INNER JOIN
CTE ON mt.myDate>=DATEADD(minute,23,CTE.myDate)
WHERE RowNum=1
)
SELECT guid
,fkGuid
,myDate
FROM CTE
WHERE RowNum=1
SQL小提琴是here
答案 1 :(得分:0)
首先,无论where
子句如何,您的连接都不会返回任何行。 Guid和rowNum都是每行的唯一键,所以如果guid是相同的,那么rowNum也是如此。通过将previousRow
中的字段添加到选择列表并运行不带where
子句的查询,您可以看到连接始终失败。
接下来,加入rowNum + 1
可以防止跳过行。您只会选择满足日期过滤器的相邻行。
可能会有一些带有递归查询的SQL voodoo会使这项工作成功,但会有很大的性能损失。过滤应用程序代码中的数据。例如,在C#中:
List<DataRow> FilterByInterval(IEnumerable<DataRow> rows, string dateColumn, int minutes)
{
List<DataRow> filteredRows = new List<DataRow>();
DateTime lastDate = DateTime.MinValue;
foreach (DataRow row in rows)
{
DateTime dt = row.Field<DateTime>(dateColumn);
TimeSpan diff = dt - lastDate;
if (diff.TotalMinutes >= minutes)
{
filteredRows.Add(row);
lastDate = dt;
}
}
return rows;
}