Sql server 将SQL Server(非T-SQL)中的小时数转换为天和小时数
我有一些小时,我需要以天和小时的形式显示 此数字源自Sql server 将SQL Server(非T-SQL)中的小时数转换为天和小时数,sql-server,Sql Server,我有一些小时,我需要以天和小时的形式显示 此数字源自DATEDIFF指令 对于小于24的数字,我只希望显示小时-即,21小时 对于较大的数字,我希望显示天和小时-即,3天,14小时 我不需要显示任何小于小时的单位,值应该向下舍入到前一个小时,因此1小时59分钟等于1小时 我不能使用存储过程-它必须作为单个select语句运行 我知道我可以使用模计算值,因此假设71小时: select concat((71 - (71 % 24)) / 24, ' days, ', 71 % 24, ' hour
DATEDIFF
指令
对于小于24的数字,我只希望显示小时-即,21小时
对于较大的数字,我希望显示天和小时-即,3天,14小时
我不需要显示任何小于小时的单位,值应该向下舍入到前一个小时,因此1小时59分钟等于1小时
我不能使用存储过程-它必须作为单个select语句运行
我知道我可以使用模计算值,因此假设71小时:
select concat((71 - (71 % 24)) / 24, ' days, ', 71 % 24, ' hours')
然而,这有点混乱,因为语句必须是单选的,所以我必须计算DATEDIFF
3次,如下所示
SELECT CONCAT (
(DATEDIFF(HOUR, StartDate, EndDate) -
(DATEDIFF(HOUR, StartDate, EndDate) % 24)) / 24,
' days, ',
DATEDIFF(HOUR, StartDate, EndDate) % 24,
' hours')
FROM RecordsTable
是否可以直接使用内置SQL命令将小时数格式化为天和小时,或者如果不行,select(datediff(hour,StartDate,EndDate)
转换为一个变量,我可以在单个select中重用该变量
编辑-根据建议,解决方案是使用CTE,如下所示:
WITH totalhours (htotal) AS
(
SELECT
DATEDIFF(HOUR, StartDate, EndDate) AS htotal
FROM
RecordsTable
)
SELECT
CONCAT ((htotal - (htotal % 24)) / 24,
' days, ',
htotal % 24,
' hours')
FROM
RecordsTable;
使用CTE生成一次总计,并在select中根据CTE引用该总计。或者使用子查询生成一次总计,然后从子查询中选择以获得所需结果
基本问题是,您需要将总计具体化一次才能引用它;强制引擎具体化值通常是通过CTE或子查询完成的。使用CTE生成总计一次,并在选择中根据CTE引用该总计。或者使用子查询生成总计一次,然后从中选择e子查询以获得所需的结果
基本问题是您需要将总计具体化一次才能引用它;强制引擎具体化值通常通过CTE或子查询来完成。您可以使用
datetime
对象和格式字符串或datepart
执行很多操作。例如
declare @n int = 105;
select format(dateadd(day, -1, dateadd(hour, @n, '1753-1-1')), 'd h');
-- 4 9
取最小的datetime
值(1753-01-01
),加上所需的小时数,减去一天(因为在第一天您希望天数=0),然后格式化
您可以这样改进格式:
select format(dateadd(day, -1, dateadd(hour, @n, '1753-1-1')), 'd \da\y(\s), h \hour(\s)');
-- 4 day(s), 9 hour(s)
当然,这最多只能工作31天,因为到了1753年,你将从1月份进入2月份。如果是这样的话,请返回到datepart
。这更难看,但适用于更大的值
select
datepart(day, (dateadd(day, -1, dateadd(hour, @n, '1753-1-1')))),
datepart(hour, (dateadd(day, -1, dateadd(hour, @n, '1753-1-1'))));
您可以使用
datetime
对象和格式字符串或datepart
执行很多操作
declare @n int = 105;
select format(dateadd(day, -1, dateadd(hour, @n, '1753-1-1')), 'd h');
-- 4 9
取最小的datetime
值(1753-01-01
),加上所需的小时数,减去一天(因为在第一天您希望天数=0),然后格式化
您可以这样改进格式:
select format(dateadd(day, -1, dateadd(hour, @n, '1753-1-1')), 'd \da\y(\s), h \hour(\s)');
-- 4 day(s), 9 hour(s)
当然,这最多只能工作31天,因为到了1753年,你将从1月份进入2月份。如果是这样的话,请返回到datepart
。这更难看,但适用于更大的值
select
datepart(day, (dateadd(day, -1, dateadd(hour, @n, '1753-1-1')))),
datepart(hour, (dateadd(day, -1, dateadd(hour, @n, '1753-1-1'))));
您可以使用CTE获取一次日期差异。然后从CTE中选择一条SQL语句作为一条语句执行。或者使用recordstable上的子查询获取一次日期差异…这就成功了-您可以作为答案发布,我接受吗?您可以使用CTE获取一次日期差异。然后从CTE中选择一个sin将SQL语句作为一个语句来执行。或者在recordstable上使用子查询来获取datediff一次…这就成功了-你可以作为答案发布,我会接受吗?这是我第一次不得不在MSSQL上解决这些问题。我在Oracle上也做过类似的工作,但我没有受到同样的限制,并且正如能够使用用户创建的函数和存储过程一样,SQL也有可以在T-SQL中引用的用户函数和存储过程。您也可以在此处调用函数;但我发现这种方法通常也可以接受;尽管不像函数那样可重用。限制取决于我正在处理的项目h、 我最好只创建一个函数,返回两个日期的格式化字符串,但我不允许在这种情况下使用一个。很高兴我们能够在项目限制下提供帮助。祝您好运!非常感谢您的帮助!由于数据库非常大,我们将所有功能保留在.NET代码中,以便维护更容易。项目限制有时有点尴尬,但调整大小总的来说是有帮助的。这是我第一次不得不在MSSQL上解决这些问题。我在Oracle上做过类似的工作,但我没有受到同样的限制,能够使用用户创建的函数和存储过程SQL h作为用户函数和存储过程,也可以在T-SQL中引用。您也可以在此处调用函数;但我发现这种方法通常也可以接受;尽管不像函数那样可重用。限制取决于我正在处理的项目。我最好只创建一个返回表单的函数尝试了两个日期的字符串,但我不允许在这种情况下使用其中一个。很高兴我们能够在项目限制条件下提供帮助。祝您好运!非常感谢您的帮助!由于数据库非常大,我们将所有功能保留在.NET代码中,以便于维护。项目限制有点麻烦有时是d,但调整大小对总体来说是有帮助的。我刚刚尝试了一下,遗憾的是,我不得不坚持使用
datepart
解决方案,因为许多日期都在一个日历月内运行。但是我导出了格式化日期,我仍然需要使用CTE,因为它必须在剩余时间的多个点上被引用