有没有更好的方法将 SQL 日期时间从 hh:mm:ss 转换为 hhmmss?
我必须编写一个 SQL 视图,以 hhmmss 格式的字符串形式返回日期时间列的时间部分(显然 SAP BW 不理解 hh:mm:ss)。
此代码是 SAP 推荐的方法来执行此操作,但我认为必须有一种更好、更优雅的方法来完成此操作
TIME = case len(convert(varchar(2), datepart(hh, timecolumn)))
when 1 then /* Hour Part of TIMES */
case convert(varchar(2), datepart(hh, timecolumn))
when '0' then '24' /* Map 00 to 24 ( TIMES ) */
else '0' + convert(varchar(1), datepart(hh, timecolumn))
end
else convert(varchar(2), datepart(hh, timecolumn))
end
+ case len(convert(varchar(2), datepart(mi, timecolumn)))
when 1 then '0' + convert(varchar(1), datepart(mi, timecolumn))
else convert(varchar(2), datepart(mi, timecolumn))
end
+ case len(convert(varchar(2), datepart(ss, timecolumn)))
when 1 then '0' + convert(varchar(1), datepart(ss, timecolumn))
else convert(varchar(2), datepart(ss, timecolumn))
end
这实现了所需的结果,21:10:45 显示为 211045。
我喜欢更紧凑的东西并且易于阅读,但到目前为止我还没有想出任何有效的方法。
I have to write an SQL view that returns the time part of a datetime column as a string in the format hhmmss (apparently SAP BW doesn't understand hh:mm:ss).
This code is the SAP recommended way to do this, but I think there must be a better, more elegant way to accomplish this
TIME = case len(convert(varchar(2), datepart(hh, timecolumn)))
when 1 then /* Hour Part of TIMES */
case convert(varchar(2), datepart(hh, timecolumn))
when '0' then '24' /* Map 00 to 24 ( TIMES ) */
else '0' + convert(varchar(1), datepart(hh, timecolumn))
end
else convert(varchar(2), datepart(hh, timecolumn))
end
+ case len(convert(varchar(2), datepart(mi, timecolumn)))
when 1 then '0' + convert(varchar(1), datepart(mi, timecolumn))
else convert(varchar(2), datepart(mi, timecolumn))
end
+ case len(convert(varchar(2), datepart(ss, timecolumn)))
when 1 then '0' + convert(varchar(1), datepart(ss, timecolumn))
else convert(varchar(2), datepart(ss, timecolumn))
end
This accomplishes the desired result, 21:10:45 is displayed as 211045.
I'd love for something more compact and easily readable but so far I've come up with nothing that works.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
注意:
问题表明该列的数据类型为
DATETIME
,而不是较新的(SQL Server 2008)TIME
数据类型。答案:
让我们来解压一下。
,
CONVERT
将日期时间的时间部分格式化为 varchar,格式为“hh:mi:ss”(24 小时制),由格式样式值 8 指定。首先
REPLACE
函数删除冒号,以获取'hhmiss'
格式的 varchar。这应该足以获得您需要的格式的可用字符串。
后续问题
(OP问题提出)
内联表达式是否比用户定义的函数更快/更少的服务器密集度?
快速回答是肯定的。 更长的答案是:这取决于几个因素,并且您确实需要测量性能以确定这是否属实。
我创建并执行了一个基本测试用例:(
注意,udfDateTimes 函数返回指定间隔内两个日期时间值之间的所有日期时间值的集合。在本例中,我用整整两年内每分钟的行填充了虚拟表。 。
现在,用户定义的函数使用相同的语法执行与内联表达式相同的转换:
注意:我知道该函数未定义为确定性的 (我认为这需要使用模式绑定和其他一些声明来声明该函数,例如 Oracle 所需的 PRAGMA。)但是由于每个日期时间值在表中都是唯一的,因此这并不重要。函数必须对每个不同的值执行,即使它被正确地声明为DETERMINISTIC,
我不是这里的SQL Server“用户定义函数”专家,所以可能还有其他东西。我错过了这会无意中且不必要地减慢该功能。
好的。
因此,在测试中,我交替运行这些查询中的每一个,先是一个,然后是另一个,一遍又一遍地连续运行。 第一次运行的时间与后续运行的时间一致。 (通常情况并非如此,我们希望忽略第一次运行的时间。)SQL Server Management Studio 将查询运行时间报告为最接近的秒数,格式为 hh:mi:ss,这就是我在这里报告的内容。
对于此测试用例,我们观察到用户定义的函数比等效的内联表达式慢大约 45%。
华泰
NOTE:
The question says that the column is of datatype
DATETIME
, not the newer (SQL Server 2008)TIME
datatype.ANSWER:
Let's unpack that.
First,
CONVERT
formats the time portion of the datetime into a varchar, in format 'hh:mi:ss' (24-hour clock), as specified by the format style value of 8.Next, the
REPLACE
function removes the colons, to get varchar in format'hhmiss'
.That should be sufficient to get a usable string in the format you'd need.
FOLLOW-UP QUESTION
(asked by the OP question)
Is an inline expression faster/less server intensive than a user defined function?
The quick answer is yes. The longer answer is: it depends on several factors, and you really need to measure the performance to determine if that's actually true or not.
I created and executed a rudimentary test case:
(Note, the udfDateTimes function returns the set of all datetime values between two datetime values at the specified interval. In this case, I populated the dummy table with rows for each minute for two entire years. That's on the order of a million ( 2x365x24x60 ) rows.
Now, user defined function that performs the same conversion as the inline expression, using identical syntax:
NOTE: I know the function is not defined to be
DETERMINISTIC
. (I think that requires the function be declared with schema binding and some other declaration, like thePRAGMA
required Oracle.) But since every datetime value is unique in the table, that shouldn't matter. The function is going to have to executed for each distinct value, even if it were properly declared to beDETERMINISTIC
.I'm not a SQL Server 'user defined function' guru here, so there may be something else I missed that will inadvertently and unnecessarily slow down the function.
Okay.
So for the test, I ran each of these queries alternately, first one, then the other, over and over in succession. The elapsed time of the first run was right in line with the subsequent runs. (Often that's not the case, and we want to throw out the time for first run.) SQL Server Management Studio reports query elapsed times to the nearest second, in format hh:mi:ss, so that's what I've reported here.
For this test case, we observe that the user defined function is on the order of 45% slower than an equivalent inline expression.
HTH
您可以使用用户定义的函数,例如:
然后将
秒的逻辑留给读者作为练习
you could use a user-defined function like:
then
the logic for the seconds is left as an exercise for the reader
这里有一个问题。 格式化是否需要在数据库服务器上进行? 服务器本身实际上只关心数据的存储,并且针对数据的存储进行了优化。 查看数据通常是 Db 之上的 hte 层的责任(从严格的学术意义上来说,现实世界有点混乱)
例如,如果您将结果输出到绑定到 GridControl 的 ASP.NET 页面中,您将只需在绑定到列时指定 DataFormattingString 即可。 如果您使用 C# 将其写入文本文件,那么当您提取数据时,您只需将格式字符串传递给 .ToString() 函数。
如果您需要它专门位于 DbServer 上,那么几乎每个解决方案都会很混乱,因为您需要的时间格式虽然紧凑且符合逻辑,但不是服务器能够识别的时间格式,因此您需要对其进行操作作为字符串。
Here's a question. Does the formatting need to happen on the Db Server? The server itself really only care about, and is optimized for storing the data. Viewing the data is usually the responsibility of hte layer above the Db (in a strictly academic sense, the real world is a bit more messy)
For instance, if you are outputting the result into an ASP.NET page bound to a GridControl you would just specify your DataFormattingString when you bind to the column. If you were using c# to write it to a text file, when you pull the data you would just pass the format string to the .ToString() function.
If you need it to be on the DbServer specifically, then yeah pretty much every solution is going to be messy because the time format you need, while compact and logical, is not a time format the server will recognize so you will need to manipulate it as a string.
这处理 00 -> 24 转换
This handles the 00 - > 24 conversion
编辑2:更新为句柄0 --> 24 转换,以及较短的版本:
回到稍长的版本:)
Edit 2: updated to handle 0 --> 24 conversion, and a shorter version:
Back to the slightly longer version :)
选择替换(转换(varchar(15),日期时间字段,108),':','')
从表
SELECT replace(convert(varchar(15),datetimefield, 108), ':','')
from Table
选择替换('2009-05-27 12:49:19', ':', '')
2009-05-27 124919
SELECT REPLACE('2009-05-27 12:49:19', ':', '')
2009-05-27 124919