T-SQL - 两个日期时间之间每小时的分钟数

2023-12-31

我必须以下数据:

 | tid | startdate        | enddate                |
 | 1   | 2016-12-26 12:30 | 2016-12-26 15:30       |
 | 2   | 2016-12-26 13:15 | 2016-12-26 15:15       |

我想创建一个包含小时数的结果,然后是日期时间在该小时内的分钟数。

结果示例:

 | tid | hour | minutes_in |
 | 1   | 12   | 30         |
 | 1   | 13   | 60         |
 | 1   | 14   | 60         |
 | 1   | 15   | 30         |
 | 2   | 13   | 45         |
 | 2   | 14   | 60         |
 | 2   | 15   | 15         |

有什么建议么?


首先,您需要一个数字表来获取从 0 到 23 的小时数,可以使用表值构造函数相当轻松地动态创建该表:

SELECT N
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)
    ) n (N);

然后,您可以将其连接到原始数据,以将行拆分为所需的数量。然后您只需要一个 case 表达式来应用正确的逻辑来计算分钟:

WITH Numbers (Number) AS
(   SELECT N
    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)
        ) n (N)
), SampleData (tid, StartDate, EndDate) AS
(   SELECT  tid, CONVERT(DATETIME2, StartDate), CONVERT(DATETIME2, EndDate)
    FROM (VALUES 
            (1, '2016-12-26 12:30', '2016-12-26 15:30'),
            (2, '2016-12-26 13:15', '2016-12-26 15:15')
        ) d (tid, StartDate, EndDate)
)
SELECT  d.tid,
        [Hour] = n.Number,
        Minutes_in = CASE  
                        -- SPECIAL CASE: START HOUR = END HOUR
                        WHEN DATEPART(HOUR, d.StartDate) = DATEPART(HOUR, d.EndDate) 
                            THEN DATEDIFF(MINUTE, d.StartDate, d.EndDate)

                        -- FULL HOURS IN BETWEEN START AND END
                        WHEN n.Number > DATEPART(HOUR, d.StartDate) 
                            AND n.Number < DATEPART(HOUR, d.EndDate) THEN 60

                        -- START HOUR
                        WHEN n.Number = DATEPART(HOUR, d.StartDate) 
                            THEN 60 - DATEPART(MINUTE, d.StartDate)

                        -- END HOUR
                        WHEN n.Number = DATEPART(HOUR, d.EndDate) 
                            THEN DATEPART(MINUTE, d.EndDate)
                    END
FROM    SampleData d
        INNER JOIN Numbers n 
            ON n.Number >= DATEPART(HOUR, d.StartDate)
            AND n.Number <= DATEPART(HOUR, d.EndDate);

ADDENDUM

如果您需要跨越几天,那么您可以稍微改变逻辑,生成更大的数字集来覆盖更多的小时差异,然后不要加入一天中的小时,而是加入从开始日期到的小时差的数字结束日期时间:

SELECT  *
FROM    SampleData d
        INNER JOIN Numbers n 
            ON n.Number <= DATEDIFF(HOUR, d.StartDate, d.EndDate)

这意味着如果范围跨越几天,那么就没有问题,时间只是不断增加。例如

WITH Numbers (Number) AS
(   SELECT ROW_NUMBER() OVER(ORDER BY N1.N) - 1
    FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N1(N)
    CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N2 (N)
    CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N3 (N)
    CROSS JOIN (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) N4 (N)
), SampleData (tid, StartDate, EndDate) AS
(   SELECT  tid, CONVERT(DATETIME2, StartDate), CONVERT(DATETIME2, EndDate)
    FROM (VALUES 
            (1, '2016-12-26 12:30', '2016-12-26 15:30'),
            (2, '2016-12-26 13:15', '2016-12-26 15:15'),
            (3, '2016-12-26 13:15', '2016-12-27 15:15')
        ) d (tid, StartDate, EndDate)
)
SELECT  d.tid,
        [Date] = CONVERT(DATE, d.StartDate),
        [Hour] = CONVERT(TIME(0), DATEADD(HOUR, DATEPART(HOUR, d.StartDate) + n.Number, 0)),
        Minutes_in = CASE  
                        -- SPECIAL CASE: START HOUR = END HOUR
                        WHEN DATEPART(HOUR, d.StartDate) = DATEPART(HOUR, d.EndDate)
                            AND DATEDIFF(DAY, d.StartDate, d.EndDate) = 0
                            THEN DATEDIFF(MINUTE, d.StartDate, d.EndDate)

                        -- START HOUR
                        WHEN n.Number = 0
                            THEN 60 - DATEPART(MINUTE, d.StartDate)

                        -- END HOUR
                        WHEN n.Number = DATEDIFF(HOUR, d.StartDate, d.EndDate) 
                            THEN DATEPART(MINUTE, d.EndDate)

                        -- FULL HOURS IN BETWEEN START AND END
                        ELSE 60

                    END
FROM    SampleData d
        INNER JOIN Numbers n 
            ON n.Number <= DATEDIFF(HOUR, d.StartDate, d.EndDate)
ORDER BY d.tid, n.Number;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

T-SQL - 两个日期时间之间每小时的分钟数 的相关文章

  • 使用实用程序批量复制将所有表从 SQL Server 数据库导出到文件中

    我想将数据库中的所有表 bcp 到文件中 SELECT EXEC xp cmdshell bcp bcp QUOTENAME DB NAME database name QUOTENAME SCHEMA NAME SCHEMA ID sch
  • 连接到 SQL Server 数据库 C#-WinForms

    我正在制作一个桌面应用程序 我希望用户必须登录才能充分使用该程序 我已经在 www winhost com 我的网站的托管位置 上创建了一个数据库 但现在我不知道该怎么办 我一直在使用 google 和 msdn 我想知道如何以编程方式将新
  • T-SQL:检查电子邮件格式

    我有这样的场景 我需要物理数据库中的数据完整性 例如 我有一个变量 email address VARCHAR 200 我想检查一下值是否为 email address是电子邮件格式 有人知道如何检查 T SQL 中的格式吗 非常感谢 我使
  • SQL 选择另一列中具有最大值的列

    我有一个看起来像这样的表 Name Group Value A 1 0 B 1 2 C 1 5 D 2 6 E 2 0 F 3 3 我想选择每组中具有最大值的名称 例如 有 3 个组 因此结果将是 Name C because it has
  • 将整数“20160119”转换为“日”“年”“月”的不同列

    如何将一列整数转换为日期 DATE PRCP 1 19490101 25 2 19490102 5 3 19490118 18 4 19490119 386 5 19490202 38 到这样的表 days month years PRCP
  • 空间索引无助于 SQL 查询(性能非常慢)

    我正在尝试测试包含 170 万个邮政编码的表中纬度 经度值的空间索引的性能 我创建了一个地理列并向其中添加了一个索引 但是使用空间索引的查询比在同一个表中的纬度 经度列上使用 正常 索引的查询要慢得多 至少 100 倍 但是查询计划显示索引
  • 如何格式化 Pandas 中的日期列?

    我有一个数据框df看起来像这样 ID Date 0 1 2008 01 24 1 2 2007 02 17 格式为Date is Y m d 如何将日期格式化为 m d Y format 我尝试使用此语法 但它没有给出正确的格式 df Da
  • 如何从 pandas 数据框中包含文本的列中提取年份(或日期时间)

    假设我有一个 pandas 数据框 Id Book 1 Harry Potter 1997 2 Of Mice and Men 1937 3 Babe Ruth Story The 1948 Drama 948 Babe Ruth Stor
  • Python 3.6 DateTime Strptime 返回错误,而 Python 3.7 运行良好

    我刚刚为日期数据创建了一个数据类型 它返回一个datetime datetime object 这是代码 import datetime class Date def new cls dateTime args kwargs return
  • 从 java.util.TimeZone 转换为 org.joda.DateTimeZone

    在Java中如何将一个实例转换为java util TimeZone to org joda DateTimeZone并保持夏令时 Joda Time 处于维护模式 The 乔达时间 http www joda org joda time
  • 如何将可变数量的参数传递给 SQL Server 存储过程?

    我将 SQL Server 2005 用于我的小型 Web 应用程序 我想将参数传递给 SP 但有一个条件 可以不时更改的参数数量 想一想 这次我传递姓名和地址 下次我传递姓名 地址 该参数范围可以是 1 30 您使用默认参数声明该过程 并
  • 使用 min(datetime) 了解 SQL Server 行为

    长话短说 这只是我的一个愚蠢的假设 我确信一个专栏是一个日期时间 但它不是 所以不要指望在这个问题中找到任何有趣的东西 把它留在这里 以便民主党得到他的正确接受回答 我写了一个像这样的简单查询 SELECT ID MIN DateMadeA
  • PHP 查找最接近时间线期间的日期

    所以 呃 好吧 这可能会涉及到数学问题 所以希望你带上科学计算器 这是我的问题 给定初始日期 时间戳 时间段 秒 和今天的日期 时间戳 我需要找到与 period n 加上原始 初始日期一致的最近日期 到目前为止 我得到了一些运行良好的东西
  • 将多个子查询作为值插入

    假设我要插入一个有很多 fk 的表 只是为了在下面解释一下错误的说法 insert into mytable values somevalue somevalue select id from othertable1 where condi
  • SQL Server 2008 R2 中的字符映射/逐字符搜索和替换

    我在 SQL Server 2008 R2 上运行 我们在这里有一个要求 即我需要创建将某些英文字符替换为以前在遗留系统中使用的区域设置语言字符 为此 我可能会使用 T SQL 中的替换函数 但在我的实践中 我们会逐个字符地替换 例如 AS
  • 我们可以在 Azure 上的 T-SQL 过程中创建数据库范围的凭据吗

    我们可以在 Azure SQL 上的 T SQL 过程中为共享访问签名创建数据库范围的凭据吗 我们正在尝试从存储在 Azure blob 上的 csv 文件批量插入数据 以下是步骤 使用 JAVA 创建 SAS 凭证 Java将调用存储过程
  • 使用变量获取 SQL xml 属性值

    我有一个 SQL 函数 它接受一个名为attribute 这是我想要从中获取值的 xml 属性 xmlPath是完整的 XML 字符串 我的 xml 看起来像这样
  • 在 SQL Server 中执行嵌套 case 语句逻辑的最佳方法

    我正在编写一个 SQL 查询 其中返回的一些列需要根据很多条件进行计算 我目前正在使用嵌套的 case 语句 但它变得混乱 有更好的 更有组织性和 或可读性 方法吗 我使用的是 Microsoft SQL Server 2005 一个简化的
  • 带逗号和句点的 SQL Server 2005 货币格式

    有没有办法在 SQL Server 2005 中转换货币字段以对其进行格式化 例如 该字段包含 99966 00 我们希望以这种格式返回 99 966 00 convert varchar cast SalesProducts Price
  • 如何在行的列中插入当前日期

    如何将当前日期插入 MS SqlServer Mgm Studio 中 编辑数据 视图中的行列中 我想得到等价的值GetDate 函数调用 这是我希望能澄清问题的图片 您无法键入函数 因此请键入日期或以下解决方案之一 创建默认值GetDat

随机推荐