我正在尝试使用DATEDIFF()
函数来查找表中两个日期之间的差异。我遇到的问题是了解如何从表VS的开始日期中的最新日期中减去时间。
日期的格式为:YYYY-MM-DD HH:MM:SS
我已经尝试过了:
select FileName, '20:00' as StartTime, ModifiedDate, DATEDIFF(MINUTE,
'20:00', ModifiedDate) as 'BackupTime'
from BackLogData
但是它返回从开始时间开始的分钟数。
以下是表格的示例:
+-----------+-----------------------------+------------+
| StartTime | ModifiedDate | BackupTime |
+-----------+-----------------------------+------------+
| 20:00 | 2019-06-10 01:04:17.3692999 | 62817424 |
| 20:00 | 2019-06-10 00:53:23.4900986 | 62817413 |
| 20:00 | 2019-06-10 00:51:09.2363761 | 62817411 |
+-----------+-----------------------------+------------+
正确的表格:
+-----------+-----------------------------+------------+--+
| StartTime | ModifiedDate | BackupTime | |
+-----------+-----------------------------+------------+--+
| 20:00 | 2019-06-10 01:04:17.3692999 | 11 | |
| 20:00 | 2019-06-10 00:53:23.4900986 | 2 | |
| 20:00 | 2019-06-10 00:51:09.2363761 | 291 | |
+-----------+-----------------------------+------------+--+
答案 0 :(得分:1)
您可以花费几分钟来计算差异,并使用dateadd
和cast
将其转换为时间数据类型。请注意,如果您的差异大于24小时,则此方法将无效(时间数据类型最多存储24小时)。
SELECT FileName, '20:00' AS StartTime, ModifiedDate,
cast(dateadd(minute,DATEDIFF(MINUTE, RecordDate, ModifiedDate),'19000101') as time(0)) AS 'BackupTime'
FROM BackLogData
示例:
SELECT
cast(dateadd(minute,DATEDIFF(MINUTE, '2019-05-05 16:00:00', '2019-05-05 18:00:00'),'19000101') as time(0)) AS 'BackupTime'
输出:
02:00:00
答案 1 :(得分:1)
如果您想要的只是从'20:00'小时开始的分钟数与ModifiedDate的时间之差,则只需比较时间值:
尝试:
✔ Builder initialized
16:50:48
✔ Nuxt files generated
16:50:48
✔ Client
Compiled successfully in 22.22s
ERROR (node:9473) DeprecationWarning: Tapable.plugin is deprecated. Use new API on
.hooks instead 16:50:56
Hash: 9ca2420933de76ba890d
Version: webpack 4.33.0
Time: 22216ms
Built at: 06/20/2019 4:51:18 PM
您获得一个奇怪的大价值是因为您试图从根本上找到1900-01-01 20:00与ModifiedDate之间的区别。
答案 2 :(得分:1)
Marc Guillot处在正确的轨道上,但我发现他的查询存在一些问题。这是一个修订:
--this is setup, you don't need this
CREATE TABLE t
([StartTime] time, [ModifiedDate] datetime)
;
INSERT INTO t
([StartTime], [ModifiedDate])
VALUES
('20:00', '2019-06-10 01:04:17'),
('20:00', '2019-06-10 00:53:23'),
('20:00', '2019-06-10 00:51:09')
;
--we now have a table with a TIME column (cast it in the cte if yours is not), a DATETIME
with LOGS as (
select StartTime,
ModifiedDate,
DATEADD(DAY, -1, CAST(CAST(ModifiedDate as DATE) as DATETIME)) as ModifiedMidnightDayBefore,
CAST(StartTime as DateTime) as StartDateTime,
row_number() over (order by ModifiedDate) as num
from t
)
select curr.StartTime,
curr.ModifiedDate,
datediff(minute,
COALESCE(
prev.ModifiedDate,
curr.ModifiedMidnightDayBefore + curr.StartDateTime
),
curr.ModifiedDate) as BackupTime
from
LOGS curr
left join LOGS as prev on prev.num = curr.num - 1
order by curr.num
LOGS CTE在num = num-1上与其自身相连,从而将当前行和前一行数据放在一起。一行将没有以前的数据(空白),因此当我们进行datediff时,我们使用合并,就像ISNULL一样,但所有主要数据库供应商都支持。 COALESCE返回第一个非null参数。如果修改后的日期没有PREVious值,则用于填充值
prev vs current的DATEDIFF相当明显。如果没有以前的值,这就是逻辑上的窍门:
CTE还将修改后的日期日期时间转换为日期,以删除时间部分(将其设置为午夜)并返回日期时间(因此它从dateadd中出现为日期时间)。 Dateadd从中减去一天,因此它是前一天的午夜,然后我们将开始时间(晚上8点)添加到此。因此,有效地将表中的最小日期转换为午夜,然后推迟一天,然后添加晚上8点,因此它变为“修改日期前一天的晚上8点”,然后我们可以将日期精确地调整为291分钟>
答案 3 :(得分:0)
要获取上一次时间,您可以将表自身连接起来。但是首先我要在CTE上对行进行编号,因此您现在可以设置一个简单的条件以将每一行与上一行连接起来。
此查询返回每个ModifiedTime与上一个ModifiedTime(或第一行的StartDate)之间的差,从而得出已发布的所需结果集:
declare @StartTime time = convert(time, '20:00');
declare @StartDate datetime = (select convert(datetime, dateadd(day, -1, convert(date, max(ModifiedDate)))) +
convert(datetime, @StartTime)
from BackLogData);
with LOGS as (
select ModifiedDate,
row_number() over (order by ModifiedDate) as num
from BackLogData
)
select @StartTime as StartTime,
LOGS.ModifiedDate,
datediff(minute,
case when LOGS.num = 1 then @StartDate else PREVIOUS.ModifiedDate end,
LOGS.ModifiedDate) as BackupTime
from LOGS
left join LOGS as PREVIOUS on PREVIOUS.num = LOGS.num - 1
order by LOGS.num
PS:正如Caius Jard所指出的那样,为了能够直接计算ModifiedDate和StartTime之间的时间差,我们必须使用上一个ModifiedDate的日期部分减去一个(表示它从前一天开始)的日期部分将StartTime转换为日期时间。