Có cách nào để lấy sự khác biệt giữa hai datetime
trong máy chủ sql?
Ví dụ, ngày của tôi là
2010-01-22 15:29:55.090
2010-01-22 15:30:09.153
Vì vậy, kết quả nên được 14.063 seconds
.
Có cách nào để lấy sự khác biệt giữa hai datetime
trong máy chủ sql?
Ví dụ, ngày của tôi là
2010-01-22 15:29:55.090
2010-01-22 15:30:09.153
Vì vậy, kết quả nên được 14.063 seconds
.
Câu trả lời:
Chỉ cần lưu ý thêm về DateDiff, nó tính số lần bạn vượt qua ranh giới mà bạn chỉ định làm đơn vị của mình, vì vậy sẽ có vấn đề nếu bạn đang tìm kiếm khoảng thời gian chính xác. ví dụ
select datediff (m, '20100131', '20100201')
đưa ra câu trả lời là 1, bởi vì nó vượt qua ranh giới từ tháng 1 đến tháng 2, vì vậy mặc dù khoảng thời gian là 2 ngày, dateiff sẽ trả về giá trị 1 - nó vượt qua 1 ranh giới ngày.
select datediff(mi, '2010-01-22 15:29:55.090' , '2010-01-22 15:30:09.153')
Cung cấp giá trị 1, một lần nữa, nó đã vượt qua ranh giới phút một lần, vì vậy, mặc dù khoảng 14 giây, nó sẽ được trả về dưới dạng một phút khi sử dụng Minutes làm đơn vị.
SELECT DATEDIFF (MyUnits, '2010-01-22 15:29:55.090', '2010-01-22 15:30:09.153')
Thay thế "MyUnits" dựa trên DATEDIFF trên MSDN
Tôi có thể đề cập đến bốn chức năng quan trọng của MS SQL Server có thể rất hữu ích:
1) Hàm DATEDIFF () chịu trách nhiệm tính toán sự khác biệt giữa hai ngày, kết quả có thể là " năm quý tháng ngày năm năm ngày tuần giờ phút giây mili giây micro giây nano giây ", được chỉ định trên tham số đầu tiên ( datepart ):
select datediff(day,'1997-10-07','2011-09-11')
2) Bạn có thể sử dụng hàm GETDATE () để lấy thời gian thực và tính toán chênh lệch của một số ngày và ngày thực tế:
select datediff(day,'1997-10-07', getdate() )
3) Một hàm quan trọng khác là DATEADD () , được sử dụng để chuyển đổi một số giá trị trong datetime bằng cách sử dụng cùng một phần ngày của dateiff , mà bạn có thể thêm (với giá trị dương) hoặc giá trị con (với giá trị âm) vào một ngày cơ sở:
select DATEADD(day, 45, getdate()) -- actual datetime adding 45 days
select DATEADD( s,-638, getdate()) -- actual datetime subtracting 10 minutes and 38 seconds
4) Hàm CONVERT () được tạo ra để định dạng ngày tháng như bạn cần, nó không phải là hàm tham số, nhưng bạn có thể sử dụng một phần của kết quả để định dạng kết quả như bạn cần:
select convert( char(8), getdate() , 8) -- part hh:mm:ss of actual datetime
select convert( varchar, getdate() , 112) -- yyyymmdd
select convert( char(10), getdate() , 20) -- yyyy-mm-dd limited by 10 characters
DATETIME lạnh được tính bằng giây và một kết quả thú vị khi kết hợp bốn chức năng này là hiển thị sự khác biệt định dạng um giờ, phút và giây ( hh: mm: ss ) giữa hai ngày:
declare @date1 datetime, @date2 datetime
set @date1=DATEADD(s,-638,getdate())
set @date2=GETDATE()
select convert(char(8),dateadd(s,datediff(s,@date1,@date2),'1900-1-1'),8)
... kết quả là 00:10:38 (638 giây = 600 giây + 38 giây = 10 phút 38 giây)
Một vi dụ khac:
select distinct convert(char(8),dateadd(s,datediff(s, CRDATE , GETDATE() ),'1900-1-1'),8) from sysobjects order by 1
Tôi đã thử cách này và nó hoạt động. Tôi đã sử dụng phiên bản SQL Server 2016
SELECT DATEDIFF(MILLISECOND,'2010-01-22 15:29:55.090', '2010-01-22 15:30:09.153')/1000.00;
Các hàm DATEDIFF khác nhau là:
SELECT DATEDIFF(year, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(quarter, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(month, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(dayofyear, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(day, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(week, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(hour, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(minute, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(second, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
SELECT DATEDIFF(millisecond, '2005-12-31 23:59:59.9999999', '2006-01-01 00:00:00.0000000');
Tham khảo: https://docs.microsoft.com/en-us/sql/t-sql/functions/datediff-transact-sql?view=sql-server-2017
Ok, tất cả chúng ta đều biết câu trả lời liên quan đến DATEDIFF()
. Nhưng điều đó chỉ mang lại cho bạn một nửa kết quả mà bạn có thể đạt được. Điều gì sẽ xảy ra nếu bạn muốn nhận kết quả ở định dạng con người có thể đọc được, về Phút và Giây giữa hai DATETIME
giá trị?
Các CONVERT()
, DATEADD()
và tất nhiên DATEDIFF()
chức năng này là hoàn hảo cho một kết quả dễ dàng dễ đọc hơn mà khách hàng của bạn có thể sử dụng, thay vì một số.
I E
CONVERT(varchar(5), DATEADD(minute, DATEDIFF(MINUTE, date1, date2), 0), 114)
Điều này sẽ cung cấp cho bạn một cái gì đó như:
HH: MM
Nếu bạn muốn chính xác hơn, chỉ cần tăng VARCHAR()
.
CONVERT(varchar(12), DATEADD(minute, DATEDIFF(MINUTE, date1, date2), 0), 114)
HH: MM.SS.MS
Nội bộ trong SQL Server ngày được lưu trữ dưới dạng 2 số nguyên. Số nguyên đầu tiên là số ngày trước hoặc sau ngày gốc (1900/01/01). Số nguyên thứ hai lưu trữ số tích tắc đồng hồ sau nửa đêm, mỗi tích tắc là 1/300 giây.
Bởi vì điều này, tôi thường thấy cách đơn giản nhất để so sánh các ngày là chỉ cần trừ chúng đi. Điều này xử lý 90% các trường hợp sử dụng của tôi. Ví dụ,
select date1, date2, date2 - date1 as DifferenceInDays
from MyTable
...
Khi tôi cần câu trả lời trong các đơn vị khác với ngày, tôi sẽ sử dụng DateDiff .
Có một số cách để xem xét sự khác biệt về ngày tháng và nhiều cách khác khi so sánh ngày / giờ. Đây là những gì tôi sử dụng để nhận được sự khác biệt giữa hai ngày được định dạng là "HH: MM: SS":
ElapsedTime AS
RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) / 3600 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 3600 / 60 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 60 AS VARCHAR(2)), 2)
Tôi đã sử dụng cột này cho một cột được tính toán, nhưng bạn có thể viết lại nó dưới dạng UDF hoặc phép tính truy vấn. Lưu ý rằng logic này làm tròn số giây phân số xuống; 00: 00.00 đến 00: 00.999 được coi là 0 giây và được hiển thị là "00:00:00".
Nếu bạn dự đoán rằng khoảng thời gian có thể dài hơn một vài ngày, mã này sẽ chuyển sang định dạng D: HH: MM: SS khi cần:
ElapsedTime AS
CASE WHEN DATEDIFF(S, StartDate, EndDate) >= 359999
THEN
CAST(DATEDIFF(S, StartDate, EndDate) / 86400 AS VARCHAR(7)) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 86400 / 3600 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 3600 / 60 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 60 AS VARCHAR(2)), 2)
ELSE
RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) / 3600 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 3600 / 60 AS VARCHAR(2)), 2) + ':'
+ RIGHT('0' + CAST(DATEDIFF(S, StartDate, EndDate) % 60 AS VARCHAR(2)), 2)
END
Truy vấn sau đây sẽ cung cấp thông tin chính xác mà bạn đang tìm kiếm.
select datediff(second, '2010-01-22 15:29:55.090' , '2010-01-22 15:30:09.153')
Đây là liên kết từ MSDN cho tất cả những gì bạn có thể làm với hàm dateiff. https://msdn.microsoft.com/en-us/library/ms189794.aspx
SELECT DATEDIFF(yyyy, '2011/08/25', '2017/08/25') AS DateDiff
Nó cho bạn sự khác biệt giữa hai ngày trong năm
Kết quả là đây (2017-2011) = 6
Cú pháp:
DATEDIFF(interval, date1, date2)
Sử dụng cái này cho DD:MM:SS
:
SELECT CONVERT(VARCHAR(max), Datediff(dd, '2019-08-14 03:16:51.360',
'2019-08-15 05:45:37.610'))
+ ':'
+ CONVERT(CHAR(8), Dateadd(s, Datediff(s, '2019-08-14 03:16:51.360',
'2019-08-15 05:45:37.610'), '1900-1-1'), 8)
Vì vậy, đây không phải là câu trả lời của tôi nhưng tôi cũng vừa tìm thấy điều này trong khi tìm kiếm trên mạng cho một câu hỏi như thế này. Anh chàng này đã thiết lập một thủ tục để tính giờ, phút và giây. Các liên kết và mã:
--Creating Function
If OBJECT_ID('UFN_HourMinuteSecond') Is Not Null
Drop Function dbo.UFN_HourMinuteSecond
Go
Exec(
'Create Function dbo.UFN_HourMinuteSecond
(
@StartDateTime DateTime,
@EndDateTime DateTime
) Returns Varchar(10)
As
Begin
Declare @Seconds Int,
@Minute Int,
@Hour Int,
@Elapsed Varchar(10)
Select @Seconds = ABS(DateDiff(SECOND ,@StartDateTime,@EndDateTime))
If @Seconds >= 60
Begin
select @Minute = @Seconds/60
select @Seconds = @Seconds%60
If @Minute >= 60
begin
select @hour = @Minute/60
select @Minute = @Minute%60
end
Else
Goto Final
End
Final:
Select @Hour = Isnull(@Hour,0), @Minute = IsNull(@Minute,0), @Seconds = IsNull(@Seconds,0)
select @Elapsed = Cast(@Hour as Varchar) + '':'' + Cast(@Minute as Varchar) + '':'' + Cast(@Seconds as Varchar)
Return (@Elapsed)
End'
)
IN DATEDIFF (thứ hai, '2010-01-22 15: 29: 55.090', '2010-01-22 15: 30: 09.153')
select
datediff(millisecond,'2010-01-22 15:29:55.090','2010-01-22 15:30:09.153') / 1000.0 as Secs
result:
Secs
14.063
Chỉ nghĩ rằng tôi sẽ đề cập đến nó.
TẠO CHỨC NĂNG getDateDiffHours (@fdate AS datetime, @ tdate as datetime) RETURNS varchar (50) AS BEGIN DECLARE @cnt int DECLARE @cntDate datetime DECLARE @dayDiff int DECLARE @dayDiffWk int DECLARE @hrsDiff thập phân (18)
DECLARE @markerFDate datetime
DECLARE @markerTDate datetime
DECLARE @fTime int
DECLARE @tTime int
DECLARE @nfTime varchar(8)
DECLARE @ntTime varchar(8)
DECLARE @nfdate datetime
DECLARE @ntdate datetime
-------------------------------------
--DECLARE @fdate datetime
--DECLARE @tdate datetime
--SET @fdate = '2005-04-18 00:00:00.000'
--SET @tdate = '2005-08-26 15:06:07.030'
-------------------------------------
DECLARE @tempdate datetime
--setting weekends
SET @fdate = dbo.getVDate(@fdate)
SET @tdate = dbo.getVDate(@tdate)
--RETURN @fdate
SET @fTime = datepart(hh,@fdate)
SET @tTime = datepart(hh,@tdate)
--RETURN @fTime
if datediff(hour,@fdate, @tdate) <= 9
RETURN(convert(varchar(50),0) + ' Days ' + convert(varchar(50),datediff(hour,@fdate, @tdate))) + ' Hours'
else
--setting working hours
SET @nfTime = dbo.getV00(convert(varchar(2),datepart(hh,@fdate))) + ':' +dbo.getV00(convert(varchar(2),datepart(mi,@fdate))) + ':'+ dbo.getV00(convert(varchar(2),datepart(ss,@fdate)))
SET @ntTime = dbo.getV00(convert(varchar(2),datepart(hh,@tdate))) + ':' +dbo.getV00(convert(varchar(2),datepart(mi,@tdate))) + ':'+ dbo.getV00(convert(varchar(2),datepart(ss,@tdate)))
IF @fTime > 17
begin
set @nfTime = '17:00:00'
end
else
begin
IF @fTime < 8
set @nfTime = '08:00:00'
end
IF @tTime > 17
begin
set @ntTime = '17:00:00'
end
else
begin
IF @tTime < 8
set @ntTime = '08:00:00'
end
-- used for working out whole days
SET @nfdate = dateadd(day,1,@fdate)
SET @ntdate = @tdate
SET @nfdate = convert(varchar,datepart(yyyy,@nfdate)) + '-' + convert(varchar,datepart(mm,@nfdate)) + '-' + convert(varchar,datepart(dd,@nfdate))
SET @ntdate = convert(varchar,datepart(yyyy,@ntdate)) + '-' + convert(varchar,datepart(mm,@ntdate)) + '-' + convert(varchar,datepart(dd,@ntdate))
SET @cnt = 0
SET @dayDiff = 0
SET @cntDate = @nfdate
SET @dayDiffWk = convert(decimal(18,2),@ntdate-@nfdate)
--select @nfdate,@ntdate
WHILE @cnt < @dayDiffWk
BEGIN
IF (NOT DATENAME(dw, @cntDate) = 'Saturday') AND (NOT DATENAME(dw, @cntDate) = 'Sunday')
BEGIN
SET @dayDiff = @dayDiff + 1
END
SET @cntDate = dateadd(day,1,@cntDate)
SET @cnt = @cnt + 1
END
--SET @dayDiff = convert(decimal(18,2),@ntdate-@nfdate) --datediff(day,@nfdate,@ntdate)
--SELECT @dayDiff
set @fdate = convert(varchar,datepart(yyyy,@fdate)) + '-' + convert(varchar,datepart(mm,@fdate)) + '-' + convert(varchar,datepart(dd,@fdate)) + ' ' + @nfTime
set @tdate = convert(varchar,datepart(yyyy,@tdate)) + '-' + convert(varchar,datepart(mm,@tdate)) + '-' + convert(varchar,datepart(dd,@tdate)) + ' ' + @ntTime
set @markerFDate = convert(varchar,datepart(yyyy,@fdate)) + '-' + convert(varchar,datepart(mm,@fdate)) + '-' + convert(varchar,datepart(dd,@fdate)) + ' ' + '17:00:00'
set @markerTDate = convert(varchar,datepart(yyyy,@tdate)) + '-' + convert(varchar,datepart(mm,@tdate)) + '-' + convert(varchar,datepart(dd,@tdate)) + ' ' + '08:00:00'
--select @fdate,@tdate
--select @markerFDate,@markerTDate
set @hrsDiff = convert(decimal(18,2),datediff(hh,@fdate,@markerFDate))
--select @hrsDiff
set @hrsDiff = @hrsDiff + convert(int,datediff(hh,@markerTDate,@tdate))
--select @fdate,@tdate
IF convert(varchar,datepart(yyyy,@fdate)) + '-' + convert(varchar,datepart(mm,@fdate)) + '-' + convert(varchar,datepart(dd,@fdate)) = convert(varchar,datepart(yyyy,@tdate)) + '-' + convert(varchar,datepart(mm,@tdate)) + '-' + convert(varchar,datepart(dd,@tdate))
BEGIN
--SET @hrsDiff = @hrsDiff - 9
Set @hrsdiff = datediff(hour,@fdate,@tdate)
END
--select FLOOR((@hrsDiff / 9))
IF (@hrsDiff / 9) > 0
BEGIN
SET @dayDiff = @dayDiff + FLOOR(@hrsDiff / 9)
SET @hrsDiff = @hrsDiff - FLOOR(@hrsDiff / 9)*9
END
--select convert(varchar(50),@dayDiff) + ' Days ' + convert(varchar(50),@hrsDiff) + ' Hours'
RETURN(convert(varchar(50),@dayDiff) + ' Days ' + convert(varchar(50),@hrsDiff)) + ' Hours'
KẾT THÚC
Sol-1:
select
StartTime
, EndTime
, CONVERT(NVARCHAR,(EndTime-StartTime), 108) as TimeDiff
from
[YourTable]
Sol-2:
select
StartTime
, EndTime
, DATEDIFF(hh, StartTime, EndTime)
, DATEDIFF(mi, StartTime, EndTime) % 60
from
[YourTable]
Sol-3:
select
DATEPART(hour,[EndTime]-[StartTime])
, DATEPART(minute,[EndTime]-[StartTime])
from
[YourTable]
Datepart hoạt động tốt nhất
Kiểm tra DateDiff trên Sách trực tuyến.
datediff
câu trả lời nhưng dường như không có câu trả lời nào nhắc nhở bạn rằng bạn có thể nhận được kết quả tiêu cực từ nó tùy thuộc vào thứ tự tham số.