AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 318861
Accepted
Jonathan Fite
Jonathan Fite
Asked: 2022-10-28 12:21:20 +0800 CST2022-10-28 12:21:20 +0800 CST 2022-10-28 12:21:20 +0800 CST

求当前时间 X 内的第二个(时间)区间

  • 772

对于给定的当前秒数和上下边界,我需要找到所有落在该范围内的秒数,并在 59 秒标记处结束。

不用说沙拉这个词,这里有一些示例输入和输出。

  • 如果输入为 58 秒且间隔为 +/- 5 秒,那么我想返回 58、59、0、1、2、3 和 57、56、55、54、53
  • 如果 Input 是 22 且间隔相同,那么我想返回 22、23、24、25、26、27 AND 21、20、19、18、17
  • 如果 Input 为 5 且间隔相同,那么我想返回 0、1、2、3、4、5 AND 5、7、8、9、10。

我一直在使用 TIME 数据类型来尝试使用内置的 datemath 来处理 59 秒标记附近的环绕,但我取得的成功有限。这里包括我的完整非工作版本。

我对代码的状态表示歉意,我已经研究了一段时间了,我选择留下所有的点点滴滴来充分说明我的尝试。如果我找不到更优雅的解决方案,我将不得不为我们的初始间隔值建立一个带有“正确”答案的计数表,但如果可能的话,我希望拥有比这更大的灵活性。

DECLARE @CurrentSecond SMALLINT = 22 -- DATEPART(SECOND, SYSUTCDATETIME()) 
DECLARE @LowerBoundary INT  = -5
DECLARE @UpperBoundary INT = 5

;WITH CTE_Parts AS
        (
        SELECT P.ID 
            , LowerBound = DATEPART(SECOND, DATEADD(SECOND, @LowerBoundary, CONVERT(TIME, '00:00:' + CONVERT(NVARCHAR(20), P.ID))))
            --, lowerBoundTime = DATEADD(SECOND, @LowerBoundary, CONVERT(TIME, '00:00:' + CONVERT(NVARCHAR(20), P.ID)))
            , UpperBound = DATEPART(SECOND, DATEADD(SECOND, @UpperBoundary , CONVERT(TIME, '00:00:' + CONVERT(NVARCHAR(20), P.ID)))) 
            --, UpperBoundTime = DATEADD(SECOND, @UpperBoundary , CONVERT(TIME, '00:00:' + CONVERT(NVARCHAR(20), P.ID)))
            , C.LowerBoundary_Current
            --, C.LowerBoundTime_Current
            , C.UpperBoundary_Current
            --, C.UpperBoundTime_Current
        FROM (VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9)
                    , (10), (11), (12), (13), (14), (15), (16), (17), (18), (19)
                    , (20), (21), (22), (23), (24), (25), (26), (27), (28), (29)
                    , (30), (31), (32), (33), (34), (35), (36), (37), (38), (39)
                    , (40), (41), (42), (43), (44), (45), (46), (47), (48), (49)
                    , (50), (51), (52), (53), (54), (55), (56), (57), (58), (59)
                    ) AS P (ID)
            OUTER APPLY (SELECT DATEPART(SECOND, DATEADD(SECOND, @LowerBoundary, CONVERT(TIME, '00:00:' + CONVERT(NVARCHAR(20), @CurrentSecond)))) AS LowerBoundary_Current
                                , LowerBoundTime_Current = DATEADD(SECOND, @LowerBoundary, CONVERT(TIME, '00:00:' + CONVERT(NVARCHAR(20), @CurrentSecond)))
                                , DATEPART(SECOND, DATEADD(SECOND, @UpperBoundary, CONVERT(TIME, '00:00:' + CONVERT(NVARCHAR(20), @CurrentSecond))))  AS UpperBoundary_Current
                                , UpperBoundTime_Current = DATEADD(SECOND, @UpperBoundary, CONVERT(TIME, '00:00:' + CONVERT(NVARCHAR(20), @CurrentSecond)))
                            ) AS C
        )
SELECT * 
    , Ignore = CASE WHEN @CurrentSecond + @UpperBoundary <= 59 AND @CurrentSecond + @LowerBoundary >= 0 AND ID BETWEEN LowerBoundary_Current AND UpperBoundary_Current THEN 1 
                    WHEN NOT(@CurrentSecond + @UpperBoundary <= 59 AND @CurrentSecond + @LowerBoundary >= 0)
                        AND ID >= LowerBoundary_Current
                        OR ID <= UpperBoundary_Current
                        THEN 1
                    ELSE 0 END
FROM CTE_Parts AS P 
ORDER BY P.ID

绝对清楚,上面没有做我想要做的事情(除了给我一个从 0-06 的 ID 值列表)

sql-server
  • 3 3 个回答
  • 63 Views

3 个回答

  • Voted
  1. Best Answer
    Rob Dalzell
    2022-10-29T02:28:03+08:002022-10-29T02:28:03+08:00

    假设您希望在单个结果集中(不是上面的组,加上下面的组)中返回秒的范围,以下可能会满足您的需要。

    对于给出的示例,它返回预期的(*)结果。

    (*) 我认为您的第三个示例有错字,如果它遵循与其他两个示例相同的模式,我认为应该是“如果输入为 5 且间隔相同,那么我想返回 0、1、2 , 3, 4, 5 和6 , 7, 8, 9, 10。 ”

    SET NOCOUNT ON;
    
    DECLARE @CurrentSecond SMALLINT;
    DECLARE @LowerBoundary INT;
    DECLARE @UpperBoundary INT;
    
    SET @LowerBoundary = -5;
    SET @UpperBoundary = 5;
    SET @CurrentSecond = 58;
    
    ;WITH CTE (Offset)
    AS (SELECT TOP (60)
               -30 + ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
        FROM sys.objects)
    SELECT DATEPART(SECOND, DATEADD(SECOND, Offset + @CurrentSecond, 0)) AS OutputSecond
    FROM CTE
    WHERE Offset
    BETWEEN @LowerBoundary AND @UpperBoundary
    ORDER BY DATEADD(SECOND, Offset + @CurrentSecond, 0);
    
    • 2
  2. Flumox
    2022-10-29T07:36:06+08:002022-10-29T07:36:06+08:00

    Rob 的回答略有不同——您实际上并不需要使用日期函数。

    DECLARE @CurrentSecond SMALLINT;
    DECLARE @LowerBoundary INT;
    DECLARE @UpperBoundary INT;
    
    SET @LowerBoundary = -5;
    SET @UpperBoundary = 5;
    SET @CurrentSecond = 58;
    
    ;WITH CTE (Offset) as
    (
        SELECT TOP (150) -60 + ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
        FROM sys.objects
    )
    SELECT Offset % 60 AS OutputSecond
    FROM CTE
    WHERE Offset BETWEEN @CurrentSecond + @LowerBoundary AND @CurrentSecond + @UpperBoundary
    ORDER BY Offset
    
    • 0
  3. Patrick Hurst
    2022-10-29T08:21:50+08:002022-10-29T08:21:50+08:00

    我可能会这样写:

    DECLARE @CurrentSecond SMALLINT, @LowerBoundary SMALLINT, @UpperBoundary SMALLINT
    
    SET @CurrentSecond = 58
    SET @LowerBoundary = -5
    SET @UpperBoundary = 5
    
    ;WITH seconds AS (
    SELECT @CurrentSecond+@LowerBoundary AS second, 0 AS id
    UNION ALL
    SELECT CAST(CASE WHEN second+1 >= 60 THEN second+1-60
                     ELSE second+1 END AS SMALLINT), id+1 FROM seconds
     WHERE id < @UpperBoundary  + ABS(@LowerBoundary)
    )
    
    SELECT second
      FROM seconds
    
    • 0

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve