Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 将SQL Server(非T-SQL)中的小时数转换为天和小时数_Sql Server - Fatal编程技术网

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,因为它必须在剩余时间的多个点上被引用