我的客户要求。注释列
的数据模式如下:TT: 12:32,12:35 :TT:
:TT: 05:17,05:30 :TT:
:TT: 01:56,02:00 :TT:
:TT: 01:00,01:12 :TT:
我需要删除:TT:tag并从最后一个减去第一个值。 例如12:35-12:32 = 00:03。
我已应用以下代码
WITH CTE1 AS
(
SELECT (LTRIM(RTRIM(REPLACE(CAST(Note as NVarchar(4000)),':tt:','')))) AS Note
FROM UD_Notes
WHERE Note like ':t%'
)
SELECT Note FROM CTE1
现在低于结果 -
01:00,01:12
01:56,02:00
05:17,05:30
12:32,12:35
有人可以帮我解决这个问题吗?
答案 0 :(得分:2)
我有一个解决方案可以给你这样的东西:
3
13
4
12
注意:使用DATEDIFF
更新了它 WITH CTE1 AS
(
SELECT (LTRIM(RTRIM(REPLACE(CAST(Note as NVarchar(4000)),':tt:','')))) AS Note
FROM UD_Notes
WHERE Note like ':t%'
)
SELECT Note INTO #RESULT FROM CTE1
SELECT
DATEDIFF(MINUTE, CONVERT(datetime, left(CONVERT(varchar(50), LEFT(Note, CHARINDEX(',', Note) - 1)), 19)), CONVERT(datetime, left(CONVERT(varchar(50), RIGHT(Note, CHARINDEX(',', Note) - 1)), 19)))
FROM #RESULT
我已经测试了这样:
CREATE TABLE #PRERESULT(
Note text)
INSERT INTO #PRERESULT (note)
VALUES
(':TT: 12:32,12:35 :TT:'),
(':TT: 05:17,05:30 :TT:'),
(':TT: 01:56,02:00 :TT:'),
(':TT: 01:00,01:12 :TT:');
WITH CTE1 AS
(
SELECT (LTRIM(RTRIM(REPLACE(CAST(Note as NVarchar(4000)),':tt:','')))) AS Note
FROM #PRERESULT
WHERE Note like ':t%'
)
SELECT Note INTO #RESULT FROM CTE1
SELECT
DATEDIFF(MINUTE, CONVERT(datetime, left(CONVERT(varchar(50), LEFT(Note, CHARINDEX(',', Note) - 1)), 19)), CONVERT(datetime, left(CONVERT(varchar(50), RIGHT(Note, CHARINDEX(',', Note) - 1)), 19)))
FROM #RESULT
DROP TABLE #PRERESULT
DROP TABLE #RESULT
度过愉快的一天
艾蒂安
答案 1 :(得分:1)
试试这个:
select
right('00'+cast(cast(substring(ltrim(rtrim(replace(cast(Note as nvarchar(100)),':TT:',''))),7,2) as int) - cast(substring(ltrim(rtrim(replace(cast(Note as nvarchar(100)),':TT:',''))),1,2) as int) as varchar),2)
+ ':'
+ right('00'+cast(cast(substring(ltrim(rtrim(replace(cast(Note as nvarchar(100)),':TT:',''))),10,2) as int) - cast(substring(ltrim(rtrim(replace(cast(Note as nvarchar(100)),':TT:',''))),4,2) as int) as varchar),2)
from ud_notes where note like ':t%'
故障:
varchar
。答案 2 :(得分:1)
您可以使用接收字符串的标量用户定义函数(甚至包括':TT:'的整个字符串),并处理它以返回所需的结果。
通过这种方式,您可以重复使用并轻松测试。
有点像这样:
CREATE FUNCTION dbo.TimeDiff(@value AS nvarchar(4000))
RETURNS NVARCHAR(5)
AS
BEGIN
DECLARE @cleaned NVARCHAR(11)
SET @cleaned = LTRIM(RTRIM(REPLACE(@value,':TT:','')))
DECLARE @h1 int
DECLARE @m1 int
DECLARE @h2 int
DECLARE @m2 INT
DECLARE @t1 INT
DECLARE @t2 int
SET @h1 = CAST(SUBSTRING(@cleaned,1,2) AS int)
SET @m1 = CAST(SUBSTRING(@cleaned,4,2) AS int)
SET @h2 = CAST(SUBSTRING(@cleaned,7,2) AS int)
SET @m2 = CAST(SUBSTRING(@cleaned,10,2) AS int)
SET @t1 = @h1 * 60 + @m1
SET @t2 = @h2 * 60 + @m2
DECLARE @diff INT
DECLARE @diffh NVARCHAR(2)
DECLARE @diffm NVARCHAR(2)
SET @diff = @t1 - @t2
SET @diffh = RIGHT('0' + CAST(@diff / 60 AS NVARCHAR(2)),2)
SET @diffm = RIGHT('0' + CAST(@diff % 60 AS NVARCHAR(2)), 2)
RETURN @diffh + ':' + @diffm
END
你可以这样测试:
SELECT dbo.TimeDiff(':TT: 12:23,11:54 :TT:')
然后您可以在选择的句子中轻松使用此功能。当然,您可以修改实现以提高效率,或修改计算的细节。
答案 3 :(得分:1)
测试数据
DECLARE @TABLE TABLE (Note TEXT)
INSERT INTO @TABLE VALUES
(':TT: 12:32,12:35 :TT:'),
(':TT: 05:17,05:30 :TT:'),
(':TT: 01:56,02:00 :TT:'),
(':TT: 01:00,01:12 :TT:')
<强>查询强>
;WITH CTE1 AS
(
SELECT CAST(REPLACE(LEFT(Note, CHARINDEX(',', Note) -1),':tt:','') AS TIME) AS StartTime
,CAST(SUBSTRING(Note, CHARINDEX(',', Note)+ 1, 5) AS TIME) AS EndTime
FROM (SELECT CAST(Note AS VARCHAR(1000)) AS Note FROM @TABLE) A
WHERE Note like ':t%'
)
SELECT CAST(StartTime AS NVARCHAR(5)) AS StartTime
,CAST(EndTime AS NVARCHAR(5)) AS EndTime
,DATEDIFF(MINUTE, StartTime,EndTime) TimeDifference
FROM CTE1
结果集
╔═══════════╦═════════╦════════════════╗
║ StartTime ║ EndTime ║ TimeDifference ║
╠═══════════╬═════════╬════════════════╣
║ 12:32 ║ 12:35 ║ 3 ║
║ 05:17 ║ 05:30 ║ 13 ║
║ 01:56 ║ 02:00 ║ 4 ║
║ 01:00 ║ 01:12 ║ 12 ║
╚═══════════╩═════════╩════════════════╝
Working SQL FIDDLE
答案 4 :(得分:1)
嗨,Nishant试试这个:
select DATEDIFF(MI,SUBSTRING(REPLACE(Note,':TT:',''),
charindex('',REPLACE(Note,':TT:','')),
charindex(',',REPLACE(Note,':TT:',''))),
SUBSTRING(REPLACE(Note,':TT:',''),
charindex(',',REPLACE(Note,':TT:',''))+1,
len(REPLACE(colval,':TT:',''))-charindex(',',REPLACE(Note,':TT:',''))))
from UD_Notes
答案 5 :(得分:1)
如果你想得到hh:mi格式的结果:
SELECT
CONVERT(VARCHAR(5), DATEADD(minute, DATEDIFF(minute, LEFT(LTRIM(REPLACE(CONVERT(VARCHAR(8000), Note), ':TT:', '')), 5), RIGHT(RTRIM(REPLACE(CONVERT(VARCHAR(8000), Note), ':TT:', '')), 5)), 0), 14)
FROM
UD_Notes
WHERE
PATINDEX(':T%', Note) > 0
说明:提取左右时间字符串。将字符串隐式转换为时间数据,同时获得以分钟为单位的整数差异。将结果整数转换为hh:mi。
答案 6 :(得分:1)
select cast(dateadd(minute,
datediff(minute,
substring(Note, 7, 5),
substring(Note, 13, 5)
),
0) as time(0))
结果:
00:03:00
00:13:00
00:04:00
00:12:00
答案 7 :(得分:1)
我花了一段时间,而且我认为这不是最有效的方式(转换次数太多),但我有一个XML解决方案正在运行,有人可能会改进。请注意,由于您处理的时间我使用了日期函数 - ,但请务必阅读最后的警告。基本上,在您的CTE中,您将数据转换为简单的XML格式,如
<Note>
<T1>00:00</T1>
<T2>00:00</T2>
</Note>
这消除了进行字符串拆分功能的需要。现在,您可以使用DATEDIFF
,DATEADD
,CAST
和LEFT
WITH CTE1 AS
(
SELECT CAST('<Note><T1>' + REPLACE((LTRIM(RTRIM(REPLACE(CAST(Note AS NVARCHAR(4000)),
':tt:','')))), ',', '</T1><T2>') + '</T2></Note>' AS XML) AS Note
FROM UD_Notes
WHERE Note like ':t%'
)
SELECT LEFT(CAST(DATEADD(mi, DATEDIFF(mi, CAST(y.T1 AS TIME), CAST(y.T2 AS TIME)), CAST('00:00' AS TIME)) AS VARCHAR(20)), 5)
FROM (
SELECT c.value('(T1/text())[1]', 'varchar(50)') AS T1,
c.value('(T2/text())[1]', 'varchar(50)') AS T2
FROM (SELECT Note FROM CTE1) x
CROSS APPLY Note.nodes('/Note') AS T(c)) y
首先我们让CTE为我们提供XML
数据类型,然后我们可以查询这些数据类型,为我们提供两个“列”(T1
和T2
)。 SELECT
一次做了很多工作,所以我会把它分解。让我们假设您提供的示例为12:35 - 12:32 = 00:03
。
DATEDIFF(mi, CAST(y.T1 AS TIME), CAST(y.T2 AS TIME))
在这里,我们得到两列T1
和T2
以及CAST
两列TIME
类型并获得差异(即T2 - T1
)。这给我们INT
3
的差异,因此在下一位我只需将3
替换为相关部分。
所以,现在我们得到了
DATEADD(mi, 3, CAST('00:00' AS TIME))
我们在这里所做的是创建TIME
00:00
的{{1}}并在几分钟内添加我们的差异(mi
),这样就会给我们00:03
。再一次,我们将替换它。
CAST(00:03 AS VARCHAR(20))
这里很简单,我们只是得到VARCHAR
代表我们的时间。因为TIME
具有非常好的准确性,所以我们得到的秒和纳秒看起来像00:03:00.0000000
。我们想要摆脱秒和纳秒,因为我们在这里处理小时和分钟。
LEFT('00:03:00.0000000', 5)
我们将'00:03'
作为字符串留给我们。
我不打算通过查询的主体,因为虽然我可以编写它,但我认为我不能很清楚地解释它,但是有很多页面可以解释XML查询远比我更好来自MSDN的this blog post和查看t-sql中查询XML字段的this blog post。
我毫不怀疑有一个更好的方法可以做到这一点,这里的人也可以对查询给出一个很好的解释 - 请任何人都可以自由添加并解释我的努力。
<强> CAVEAT 强>
如果T1
为01:00
且T2
为12:57
,那么您将得到11:57
的答案,因为它们确实相隔11小时57分钟向前的方向。说实话,我现在没有时间研究如何让这两次给你3的结果,但是其他人可能会发现如何,我希望。
答案 8 :(得分:0)
所有答案都非常正确,我必须选择其中一个。 不幸的是我在结果集中得到了空格,因为那些空格我得到了转换错误(varchar到时间)。 我通过以下查询克服了问题,它现在正在为我工作。 感谢所有高级成员和专家为我提供的宝贵意见。 我有正确的方法来获得我想要的结果。
{
SELECT
CONVERT(VARCHAR,DATEDIFF(mi,
CAST(SUBSTRING(REPLACE(CAST(Note AS VARCHAR(1000)),':TT:',''),CHARINDEX(':',REPLACE(CAST(Note AS VARCHAR(1000)),':TT:',''))-2,CHARINDEX(':',REPLACE(CAST(Note AS VARCHAR(1000)),':TT:',''))) AS TIME)
,CAST(SUBSTRING(REPLACE(CAST(Note AS VARCHAR(1000)),':TT:',''),CHARINDEX(',',REPLACE(CAST(Note AS VARCHAR(1000)),':TT:',''))+1,5) AS Time))) + ' mins' As 'TimeDiff'
FROM UD_Notes where Note like '%:TT:%' }