我正在寻找一种方法来选择所有记录,其中一列具有相同的记录,并且日期时间彼此之间的间隔不超过5分钟。我管理一个票务系统,我试图查看5分钟内创建的所有类似票务。有关示例数据集,请参见以下内容:
|ID |Subject |CreatedDateTime |
-------------------------------------
|1 |A |2020-09-28 11:01:00|
|2 |A |2020-09-28 11:02:00|
|3 |A |2020-09-28 11:03:00|
|4 |A |2020-09-28 11:03:09|
|5 |A |2020-09-28 11:04:52|
|6 |A |2020-09-28 11:15:00|
|7 |B |2020-09-28 11:20:00|
|8 |B |2020-09-28 11:20:00|
|9 |B |2020-09-28 11:20:00|
我的目标是只选择1-5条记录,因为5条记录是同一主题,它们都是在5分钟内创建的。不应选择6-10,因为受试者数量不够多,或者超出了规定的时间范围。
下面是我到目前为止的一个测试查询,但它没有考虑5分钟的范围(我只回顾了1周,因此是该条款):
SELECT Subject,COUNT(*)
FROM TableName
WHERE CreatedDateTime > DATEADD(day, -7, GETDATE())
GROUP BY Subject
HAVING COUNT(*) > 5
ORDER BY COUNT(*) DESC;
有没有办法只在很短的时间内看到类似的记录?提前谢谢大家!
如果您希望对彼此在5分钟内的记录进行分组,那么您可以使用递归查询对日期范围进行“分组”,如下所示
with data
as (select *,row_number() over(partition by subject order by createddatetime) as rnk
from t
)
,cte
as(select id,subject,createddatetime as begin_date, createddatetime,cast(1 as int) as grp
from data
where rnk=1
union all
select b.id
,b.subject
,b.createddatetime
,case when datediff(minute,a.createddatetime,b.createddatetime) > 5 then
b.createddatetime
else
a.createddatetime
end as createddatetime
,case when datediff(minute,a.createddatetime,b.createddatetime) > 5 then
a.grp+1
else
a.grp
end as grp
from cte a
join t b
on a.id+1=b.id
and a.subject=b.subject
)
select * from cte order by 1
+----+---------+-------------------------+-------------------------+-----+
| id | subject | begin_date | createddatetime | grp |
+----+---------+-------------------------+-------------------------+-----+
| 1 | A | 2020-09-28 11:01:00.000 | 2020-09-28 11:01:00.000 | 1 |
| 2 | A | 2020-09-28 11:02:00.000 | 2020-09-28 11:01:00.000 | 1 |
| 3 | A | 2020-09-28 11:03:00.000 | 2020-09-28 11:01:00.000 | 1 |
| 4 | A | 2020-09-28 11:03:09.000 | 2020-09-28 11:01:00.000 | 1 |
| 5 | A | 2020-09-28 11:04:52.000 | 2020-09-28 11:01:00.000 | 1 |
| 6 | A | 2020-09-28 11:15:00.000 | 2020-09-28 11:15:00.000 | 2 |
| 6 | A | 2020-09-28 11:17:00.000 | 2020-09-28 11:17:00.000 | 2 |
| 7 | B | 2020-09-28 11:20:00.000 | 2020-09-28 11:20:00.000 | 1 |
| 8 | B | 2020-09-28 11:20:00.000 | 2020-09-28 11:20:00.000 | 1 |
| 9 | B | 2020-09-28 11:20:00.000 | 2020-09-28 11:20:00.000 | 1 |
+----+---------+-------------------------+-------------------------+-----+
DB小提琴链接
https://dbfiddle.uk/?rdbms=sqlserver_2019
您可以在每个记录前面和后面达到峰值,以分钟为单位查找时差,然后仅保留在5分钟内至少连接到另一条记录的记录:
WITH cte AS (
SELECT *,
DATEDIFF(minute,
LAG(CreatedDateTime) OVER (PARTITION BY Subject
ORDER BY CreatedDateTime),
CreatedDateTime) AS LagCreatedDateTime,
DATEDIFF(minute,
CreatedDateTime,
LEAD(CreatedDateTime) OVER (PARTITION BY Subject
ORDER BY CreatedDateTime))
AS LeadCreatedDateTime
FROM TableName
)
SELECT *
FROM cte
WHERE LagCreatedDateTime <= 5 OR LeadCreatedDateTime <= 5;
请参阅下面的演示链接,以获取使用示例数据运行的示例。
问题内容: 我有一个存储表,,,,如: 现在,如果我有IP地址,如何检索匹配记录? 编辑 根据戈登的答案(我遇到编译错误),这就是我的想法: 但这给了我一个错误: 有任何想法吗? 问题答案: 痛苦的。SQL Server具有糟糕的字符串操作功能。但是,它提供了。此方法将IP地址转换为较大的十进制值以进行比较: 我应该注意,IP地址通常以4字节无符号整数的形式存储在数据库中。这使比较容易得多。。。尽
范围选择器(rangeSelector)是图表中用于选择数据范围的工具,它提供了预配置的时间选择按钮,包括 1天,1周,1个月等,同时也提供时间输入框用于手动指定时间范围。 时间选择按钮 通过 rangeSelector.buttons 可以指定时间选择按钮,默认是 buttons: [{ type: 'month', count: 1, text: '1m' }, {
问题内容: T-SQL DateTime问题。 我有一组时间范围。在这些时间范围内,可能会有一组重叠的时间范围,我称之为“封锁”时间。封锁的时间不会超过一天。我想要做的是分配时间以排除阻塞时间,基本上是给我没有“阻塞”的时间范围。可以肯定的是,阻塞时间不能超出时间范围。 示例:我工作时间是从上午9点到下午5点,在下午1点有30分钟的午餐时间。我想要2行的结果:9am至1pm和1.30pm至5pm。
问题内容: 如何在MySQL中的日期范围之间选择数据。我的专栏是24小时的祖鲁时间格式。 尽管在这些时间段之间有数据,但不返回任何内容。我是否必须强制 “发件人” 和 “发件人” 字段中的值键入查询? 问题答案: 您需要更新日期格式:
我的数据库中有100000个地址(即记录)。 它们中的每一个都有自己的坐标(纬度和经度)。 现在,考虑到用户的地理位置(纬度和经度),我只想在地图上显示5英里范围内的地址(使用Google maps v3 API)。 这意味着通常在100000个地址中只需显示5或6个地址。 一种解决方案可能是检索所有记录,并在Java中应用一个公式来计算每个地址的距离,并且仅当它在范围内时才显示它。 这将浪费处理
在包含所有数据的生产性系统上。 是否有一个(最好是cql)查询可以与给定的列族或de一起平稳运行,我们必须更改设计?