在SQL Server(NOT T-SQL)中将小时数转换为天和小时

时间:2017-12-12 19:28:21

标签: sql-server

我有几个小时需要以天和小时的格式显示。

此数字来自21 hours指令。

对于小于24的数字,我希望只显示小时数 - 即3 days, 14 hours

对于较大的数字,我希望显示日期和小时 - 即select concat((71 - (71 % 24)) / 24, ' days, ', 71 % 24, ' hours')

我不需要显示任何小于小时的单位,并且值应该向下舍入到前一个小时,因此1小时59分钟将是1小时。

我无法使用存储过程 - 这必须作为单个select语句运行。

我知道我可以使用modulo来计算值,所以假设71小时:

DATEDIFF

然而这有些混乱,因为声明必须是单一选择,我将必须计算SELECT CONCAT ( (DATEDIFF(HOUR, StartDate, EndDate) - (DATEDIFF(HOUR, StartDate, EndDate) % 24)) / 24, ' days, ', DATEDIFF(HOUR, StartDate, EndDate) % 24, ' hours') FROM RecordsTable 3次,如下所示。

select (datediff(hour, StartDate, EndDate)

是否可以直接使用内置SQL命令将数小时格式化为天数和小时,或者将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:

{{1}}

2 个答案:

答案 0 :(得分:1)

使用CTE生成一次总计,并在您选择的CTE中引用该总计。或者使用子查询生成一次总计,然后从子查询中选择以获得所需的结果。

根本问题是你需要实现一次总数才能引用它;强制引擎实现值通常通过CTE或子查询来完成。

答案 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'))));