繁体   English   中英

select / 更新 SQL 时间戳差异超过 30 天的记录

[英]select / update SQL records that has a timestamp difference of more then 30 days

我需要 select 或更新上次访问后日期差超过 30 天的徽章记录中的记录。 一个 select 查询可以找到它们,所以我可以更新它们。 很难详细解释,但我举个例子:(这是一个人们扫描徽章并记录时间戳的访问系统。)我只需要在徽章进入系统超过30天时知道记录。在上一次扫描之后,+ 第一次扫描。 示例表显示了我需要的记录(我需要 5 条记录)

只有相同徽章编号的记录必须进行比较和更新。

这可以使用 TSQL 吗?

例子:

+------------------+--------------+
| TimeStamp        | Badge        |
+------------------+--------------+
| 19-10-2022 10:18 | Badge1       | <--- **select** (more the 30 days after previous scan)
| 01-01-2022 12:18 | Badge1       | <--- ok (less then 30 days)
| 08-12-2021 13:23 | Badge1       | <--- ok (less then 30 days)
| 20-11-2021 11:18 | Badge1       | <--- ok (less then 30 days)
| 22-10-2021 13:18 | Badge1       | <--- **select** (more the 30 days after previous scan)
| 23-08-2020 14:18 | Badge1       | <--- **select** (first entrance)
| 01-01-2022 09:18 | Badge12      | <--- ok (less then 30 days)
| 02-12-2021 10:18 | Badge12      | <--- **select** (more the 30 days after previous scan)
| 29-10-2021 23:18 | Badge12      | <--- ok (less then 30 days)
| 25-10-2021 12:18 | Badge12      | <--- **select** (first entrance)
+------------------+---------+----+

使用这个小提琴有示例数据库和我的错误答案https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=c1528618004f0fe6bb6319e8e638abae

帮助别人帮助你。 发布一个包含 DDL 和示例数据的脚本,可以作为编写代码的基础。

with cte as (
   select *, ROW_NUMBER() over (partition by Badge order by Timestamp) as rno
   from @x 
)
select cte.*, prior.rno as prno, datediff(day, prior.TimeStamp, cte.Timestamp) as ddif
from cte
left join cte as prior on cte.badge = prior.badge and cte.rno - 1 = prior.rno
where cte.rno = 1 or datediff(day, prior.TimeStamp, cte.Timestamp) > 30
order by cte.Badge, cte.TimeStamp;

这应该可行,但我无法在 2008 年进行测试。 小提琴来演示。 注释掉 WHERE 子句以查看为查询逻辑计算的所有行和列。 这使用 ROW_NUMBER 生成序列号,然后使用该值简单地自连接以模拟 LAG。

更新的小提琴: https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=a24d23f54030d7aadd8f889819cd4512

;WITH Ordered AS (
    SELECT *
         , ROW_NUMBER() OVER (PARTITION BY Badge ORDER BY  CONVERT(DATETIME, [scandate] ,103) DESC) rn
    FROM History 
) 
SELECT M.*, DATEDIFF(dd,  p.[scandate],m.[scandate]) DaysGap
FROM Ordered M
LEFT JOIN  Ordered P 
ON M.rn = P.rn-1 
AND M.Badge = P.Badge 
WHERE P.rn IS NULL -- first entrance
OR DATEDIFF(dd,  p.[scandate],m.[scandate]) > 30

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM