SqlSever 关于时间字段的分组查询

现有一堆条码,其中尾数a/b表示一张制品的左右
问题是在录入过程中左右录入反了,即ID 1的SHT实际对应ID 2的PCS,以此类推

区分的思路是想利用EnterTime字段,因为经过排序后可以发现同制品a、b的录入时间间隔
非常接近,那么什么语句可以限定以1秒内,2秒内的时间间隔来分组查询这些条码呢?

简单语句尝试不出来,百度也基本只有大于多少小于多少时间这种方式

img

你可以使用以下语句来实现你的需求:

SELECT * FROM table
WHERE ABS(EnterTime - LAG(EnterTime, 1) OVER (PARTITION BY a ORDER BY EnterTime)) <= INTERVAL '2' SECOND
AND ABS(EnterTime - LAG(EnterTime, 1) OVER (PARTITION BY b ORDER BY EnterTime)) <= INTERVAL '2' SECOND

在上面的语句中,我们使用了 LAG 函数来查询每个制品的上一条记录的录入时间,并使用 ABS 函数求绝对值,然后使用 INTERVAL 函数指定时间间隔,最后使用 WHERE 子句来筛选出时间间隔在 1 秒内或 2 秒内的记录。

你也可以使用 BETWEEN 子句来筛选出时间间隔在 1 秒内或 2 秒内的记录:

SELECT * FROM table
WHERE EnterTime BETWEEN LAG(EnterTime, 1) OVER (PARTITION BY a ORDER BY EnterTime) AND LAG(EnterTime, 1) OVER (PARTITION BY a ORDER BY EnterTime) + INTERVAL '2' SECOND
AND EnterTime BETWEEN LAG(EnterTime, 1) OVER (PARTITION BY b ORDER BY EnterTime) AND LAG(EnterTime, 1) OVER (PARTITION BY b ORDER BY EnterTime) + INTERVAL '2' SECOND


可以使用以下的 SQL 语句来实现分组查询:

SELECT a.*, b.*
FROM tablename a
JOIN tablename b
ON DATEDIFF(SECOND, a.EnterTime, b.EnterTime) BETWEEN 0 AND 1
AND a.ID <> b.ID

在这个语句中,我们使用了 DATEDIFF 函数来计算两个时间的差,并使用 BETWEEN 关键字来限制时间差在 1 秒内。然后使用 JOIN 语句将两张表连接起来,并使用条件语句来限制 ID 不相同。

如果要限制时间差在 2 秒内,可以将 BETWEEN 0 AND 1 改为 BETWEEN 0 AND 2。

注意:这里的表名为 tablename,请根据实际情况修改。

另外,如果想要更精细地控制时间差,可以使用以下的语句:


SELECT a.*, b.*
FROM tablename a
JOIN tablename b
ON a.EnterTime BETWEEN b.EnterTime - INTERVAL 1 SECOND AND b.EnterTime + INTERVAL 1 SECOND
AND a.ID <> b.ID

在这个语句中,我们使用了 INTERVAL 关键字来表示时间差,并使用 BETWEEN 关键字来限制a.EnterTime 的值在 b.EnterTime 的值的前后 1 秒内。如果要限制时间差在 2 秒内,可以将 INTERVAL 1 SECOND 改为 INTERVAL 2 SECOND。

还有一种方法是使用滑动窗口,可以使用以下的 SQL 语句来实现:

SELECT * FROM (
  SELECT a.*, b.*,
  ROW_NUMBER() OVER (PARTITION BY a.ID ORDER BY a.EnterTime) AS a_rn,
  ROW_NUMBER() OVER (PARTITION BY b.ID ORDER BY b.EnterTime) AS b_rn
  FROM tablename a
  JOIN tablename b
  ON a.ID <> b.ID
) t
WHERE a_rn = b_rn

在这个语句中,我们使用了 ROW_NUMBER 函数来计算行号,并使用 OVER 关键字和 PARTITION BY 子句来对 ID 进行分组。然后使用 JOIN 语句将两张表连接起来,并使用条件语句限制 ID 不相同。最后使用条件语句限制 a_rn 和 b_rn 相等,就可以得到录入时间差在 1 秒内的数据。

注意:如果要限制时间差在 2 秒内,可以将上面的语句改为:

SELECT * FROM (
  SELECT a.*, b.*,
  ROW_NUMBER() OVER (PARTITION BY a.ID ORDER BY a.EnterTime) AS a_rn,
  ROW_NUMBER() OVER (PARTITION BY b.ID ORDER BY b.EnterTime) AS b_rn
  FROM tablename a
  JOIN tablename b
  ON a.ID <> b.ID
  AND ABS(DATEDIFF(SECOND, a.EnterTime, b.EnterTime)) <= 2
) t
WHERE a_rn = b_rn

在这个语句中,我们使用了 ABS 函数来计算两个时间的差的绝对值,然后使用条件语句限制时间差小于等于 2 秒。

最后,如果想要计算每对数据的时间差,可以使用以下的语句:

SELECT a.*, b.*, DATEDIFF(SECOND, a.EnterTime, b.EnterTime) AS diff
FROM tablename a
JOIN tablename b
ON a.ID <> b.ID
AND ABS(DATEDIFF(SECOND, a.EnterTime, b.EnterTime)) <= 2

在这个语句中,我们使用了 DATEDIFF 函数来计算两个时间的差,然后使用 AS 关键字将结果命名为 diff。

希望这些信息对你有帮助!望采纳。

你可以使用 DATEDIFF 函数来计算两个时间之间的差值,然后将结果与你要的时间间隔进行比较。

下面是一个例子,假设你想要找出 EnterTime 在 1 秒内的记录:

SELECT *
FROM your_table
WHERE DATEDIFF(second, EnterTime, other_time_column) <= 1

如果你想要找出 EnterTime 在 2 秒内的记录,只需要将 1 改为 2 即可。

需要注意的是,这里的时间间隔是指两个时间之间的差值,并不是两个时间之间的时间跨度。例如,如果 EnterTime 为 '2022-01-01 10:00:00',other_time_column 为 '2022-01-01 10:00:01',那么这两个时间之间的差值就是 1 秒。

如果你想要根据这些条件分组查询,可以使用 GROUP BY 子句。例如:

SELECT *
FROM your_table
WHERE DATEDIFF(second, EnterTime, other_time_column) <= 1
GROUP BY EnterTime

这样就可以得到所有 EnterTime 在 1 秒内的记录的分组了。

按下图的,后面一个pcs就是反过来的,相同产品的多个数据限制时间3秒内

img


DECLARE @t TABLE (ID INT, Sht VARCHAR(100), EnterTime datetime,pcs VARCHAR(100))
INSERT @t(ID,Sht,enterTime,pcs) VALUES
(1,'111a','2022-12-07 03:18:10.303','DTT250000001'),
(2,'111b','2022-12-07 03:18:12.060','DTT250000002'),
(3,'222a','2022-12-07 09:45:53.600','DTT250000003'),
(4,'222b','2022-12-07 09:45:54.893','DTT250000004'),
(5,'333a','2022-12-07 12:01:43.740','DTT250000005'),
(6,'333b','2022-12-07 12:01:45.213','DTT250000006')
SELECT  *
FROM    @t a
        INNER JOIN @t b ON SUBSTRING(a.Sht, 1, LEN(a.Sht) - 1) = SUBSTRING(b.Sht, 1, LEN(b.Sht) - 1)
                           AND   (SUBSTRING(a.Sht, LEN(a.Sht), 1) <> SUBSTRING(b.Sht, LEN(b.Sht), 1))
                           AND ABS(DATEDIFF(MILLISECOND,a.entertime,b.entertime))<3000

示例代码:

SELECT ID, Sht, EnterTime, pcs
FROM table
GROUP BY ID, Sht, EnterTime, pcs
HAVING DATEDIFF(second, EnterTime, pcs) <= 2

这段代码会查询出所有满足条件的制品,即录入时间之差在 2 秒以内的制品。

如果想要查询出录入时间之差在 1 秒以内的制品,只需要将 2 改为 1 即可。
仅供参考,望采纳,谢谢。

可以使用 SqlServer 中的 DATEDIFF 函数来计算两个日期之间的时间间隔,并使用该时间间隔来分组查询。

例如如果想要计算出两条记录的 EnterTime 字段之间小于 1 秒的记录,可以使用以下语句:

SELECT *
FROM table
WHERE DATEDIFF(second, EnterTime, LEAD(EnterTime) OVER (PARTITION BY SHT ORDER BY EnterTime)) < 1

想要计算出两条记录的 EnterTime 字段之间小于 2 秒的记录,可以使用以下语句:

SELECT *
FROM table
WHERE DATEDIFF(second, EnterTime, LEAD(EnterTime) OVER (PARTITION BY SHT ORDER BY EnterTime)) < 2

您可以使用 SQL 中的 "GROUP BY" 和 "HAVING" 子句来限制时间间隔在 1 秒或 2 秒之内的数据

SELECT a, b, COUNT(*)
FROM table_name
GROUP BY a, b
HAVING TIMESTAMPDIFF(SECOND, MIN(EnterTime), MAX(EnterTime)) <= 1 OR TIMESTAMPDIFF(SECOND, MIN(EnterTime), MAX(EnterTime)) <= 2