Thanks Jeff for the performance analysis. The two main reasons that it is slower are:
1) Its coded as a scalar function
2) It also handles days, i.e., it outputs a string like DDD:HH:MM:SS.mmm
I've altered things a bit and here are the results from 1,000,000 test rows:
Your code outputting [HHH:MM:SS.mmm]:
STUFF(CONVERT(VARCHAR(20),EndDT-StartDT,114),1,2,DATEDIFF(hh,0,EndDT-StartDT))
CPU time = 1202 ms, elapsed time = 1182 ms.
My refactored code outputting [DDD:HH:MM:SS.mmm]:
-- Emit the days number...
Cast(DateDiff(dd,StartDT,EndDT)
-- ...subtracting a day when the times are inverted.
-Case when Convert(VarChar,StartDT,114)>Convert(VarChar,EndDT,114) then 1 else 0 End as VarChar)
-- Emit the separator and time components.
+':'+Convert(VarChar,EndDT-StartDT,114)
CPU time = 2527 ms, elapsed time = 2381 ms.
I'm willing to eat the extra time to get the elapsed time in DDD:HH:MM:SS.mmm format, especially since we only use this to output elapsed time between DML in procedures during development.
I didn't realize that you could perform simple math (+, -) on DateTime types! Learn something new everyday. Thanks, you rock!