SQL SERVER: Tính năng range datetime
Day
Day Range
Tìm thời gian bắt đầu và ngày kết thúc của một ngày.
Hide
DECLARE @dateTimeNow DATETIME ='2019-07-01 17:20:00' /*yyyy-MM-dd HH:mm:ss*/
--DECLARE @dateTimeNow DATETIME = GETDATE(); /*now*/
SELECT
[StartDateTime] = DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow), 0),
[EndDateTime] = DATEADD(SECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow) + 1, 0));
Populate Days With Range
Tạo danh sách ngày với phạm vi hàng ngày:
Hide
DECLARE @startDateTime DATETIME ='2019-09-21', _
@endDateTime DATETIME ='2019-09-30'; /*yyyy-MM-dd*/
--SET @startDateTime = GETDATE(); _
SET @endDateTime = @startDateTime + 10; /*now*/
WITH Dates([Date])
AS
(
SELECT [Date]= @startDateTime
UNION ALL
SELECT [Date] + 1
FROM Dates
WHERE [Date] + 1 <= @endDateTime
),
DateRange([Date], [StartDateTime], [EndDateTime])
AS
(
SELECT
[Date],
DATEADD(DAY, DATEDIFF(DAY, 0, [Date]), 0),
DATEADD(SECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, [Date]) + 1, 0))
FROM Dates
)
SELECT *
FROM DateRange
OPTION (MAXRECURSION 0)
Week
Week Range
Tìm thời gian bắt đầu và ngày kết thúc của một tuần.
Hide
DECLARE @dateTimeNow DATETIME ='2019-07-01' /*yyyy-MM-dd*/
--DECLARE @dateTimeNow DATETIME = GETDATE(); /*now*/
SELECT
[StartDate] = DATEADD(dd, -(DATEPART(WEEKDAY, @dateTimeNow)-1), _
DATEADD(dd, DATEDIFF(dd, 0, @dateTimeNow), 0)),
[EndDate] = DATEADD(dd, 7-(DATEPART(WEEKDAY, @dateTimeNow)), _
DATEADD(dd, DATEDIFF(dd, 0, @dateTimeNow), 0));
SELECT
[StartDateTime] = DATEADD(DAY, -(DATEPART(WEEKDAY, @dateTimeNow)-1), _
DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow), 0)),
[EndDateTime] = DATEADD(DAY, 7-(DATEPART(WEEKDAY, @dateTimeNow)), _
DATEADD(SECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, @dateTimeNow) + 1, 0)))
Populate Weeks With Range
Tạo danh sách tuần với phạm vi hàng tuần:
Hide
DECLARE @startDateTime DATETIME = '2019-04-01 03:20:00', _
@endDateTime DATETIME = '2019-04-30 03:20:00';
WITH Weeks([Date])
AS
(
SELECT [Date] = @startDateTime
UNION ALL
SELECT DATEADD(DAY, 7, [Date])
FROM Weeks
WHERE DATEADD(DAY, 7, [Date]) <= @endDateTime
),
WeekRange([Date], [StartDateTime], [EndDateTime])
AS
(
SELECT
[Date],
DATEADD(DAY, -(DATEPART(WEEKDAY, [Date])-1), _
DATEADD(DAY, DATEDIFF(DAY, 0, [Date]), 0)),
DATEADD(DAY, 7-(DATEPART(WEEKDAY, [Date])), _
DATEADD(SECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, [Date]) + 1, 0)))
FROM Weeks
)
SELECT *
FROM WeekRange
OPTION (MAXRECURSION 0)
Change Week Start Day
Trong SQL Server, Chủ nhật là ngày bắt đầu mặc định trong tuần. Có một hàm @@ DATEFIRST, trả về ngày bắt đầu tuần hiện tại (giá trị của SET DATEFIRST). Để thay đổi ngày bắt đầu tuần mặc định, chúng tôi có thể đặt bất kỳ giá trị ngày bắt đầu tuần nào trong khoảng từ 1-7 đến DATEFIRST. Sau khi thiết lập ngày bắt đầu tuần dự kiến, tất cả chúng tôi đã chạy trên các truy vấn.
Hide
SELECT @@DATEFIRST;
SET DATEFIRST 7; /*setting week start to 'Sunday'*/
@@ DATEFIRST là cục bộ của phiên. Chúng tôi có thể xác minh nó bằng cách mở các tab khác nhau trong SQL Server Management Studio và thực thi mã set / select trong các tab khác nhau.
Month
Month Range
Tìm thời gian bắt đầu và ngày kết thúc của một tháng.
Hide
DECLARE @dateTimeNow DATETIME ='2019-07-01'; /*yyyy-MM-dd*/
--DECLARE @dateTimeNow DATETIME = GETDATE(); /*now*/
SELECT
[StartDate] = DATEADD(mm, DATEDIFF(m, 0, @dateTimeNow), 0),
[EndDate] = DATEADD(mm, DATEDIFF(m, 0, @dateTimeNow) + 1, -1);
SELECT
[StartDateTime] = DATEADD(mm, DATEDIFF(m, 0, @dateTimeNow), 0),
[EndDateTime] = DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, @dateTimeNow) + 1, 0));
Populate Months With Range
Tạo danh sách tháng với phạm vi hàng tháng:
Hide
DECLARE @startDateTime DATETIME ='2019-01-18 03:20:00', _
@endDateTime DATETIME ='2019-12-18 04:20:00';
WITH Months([Date])
AS
(
SELECT [Date] = @startDateTime
UNION ALL
SELECT DATEADD(MONTH, 1, [Date])
FROM Months
WHERE DATEADD(MONTH, 1, [Date]) <= @endDateTime
),
MontRange([Date], [StartDateTime], [EndDateTime])
AS
(
SELECT
[Date],
DATEADD(mm, DATEDIFF(m, 0, [Date]), 0),
DATEADD(s, -1, DATEADD(mm, DATEDIFF(m, 0, [Date]) + 1, 0))
FROM Months
)
SELECT *
FROM MontRange
OPTION (MAXRECURSION 0)
Year
Year Range
Tìm thời gian bắt đầu và ngày kết thúc của một năm.
Hide
DECLARE @dateTimeNow DATETIME ='2019-07-01' /*yyyy-MM-dd*/
--DECLARE @dateTimeNow DATETIME = GETDATE(); /*now*/
SELECT
[StartDate] = DATEADD(yy, DATEDIFF(yy, 0, @dateTimeNow), 0),
[EndDate] = DATEADD(yy, DATEDIFF(yy, 0, @dateTimeNow) + 1, -1)
SELECT
[StartDateTime] = DATEADD(yy, DATEDIFF(yy, 0, @dateTimeNow), 0),
[EndDateTime] = DATEADD(s, -1, DATEADD(yy, DATEDIFF(yy, 0, @dateTimeNow) + 1, 0))
Populate Years With Range
Tạo danh sách năm với phạm vi hàng năm:
Hide
DECLARE @startDateTime DATETIME ='2017-12-17 03:20:00', _
@endDateTime DATETIME ='2019-12-19 04:20:00';
WITH Years([Date])
AS
(
SELECT [Date] = @startDateTime
UNION ALL
SELECT DATEADD(YEAR, 1, [Date])
FROM Years
WHERE DATEADD(YEAR, 1, [Date]) <= @endDateTime
),
YearRange([Date], [StartDateTime], [EndDateTime])
AS
(
SELECT
[Date],
DATEADD(yy, DATEDIFF(yy, 0, [Date]), 0),
DATEADD(s, -1, DATEADD(yy, DATEDIFF(yy, 0, [Date]) + 1, 0))
FROM Years
)
SELECT *
FROM YearRange
OPTION (MAXRECURSION 0)
DateTime Function
Sau khi lặp lại cùng một mã nhiều lần, tôi đã tự hỏi tại sao không tạo hàm trợ giúp thời gian ngày để tìm thời gian ngày bắt đầu / kết thúc. Vì vậy, ở đây chúng tôi có nó.
Create Function
IF OBJECT_ID(N'DateTimePart', N'FN') IS NOT NULL
DROP FUNCTION DateTimePart;
GO
CREATE FUNCTION DateTimePart(@dateTime DATETIME, @startOrEnd VARCHAR(10))
RETURNS DATETIME
AS
BEGIN
/*validations*/
IF @dateTime IS NULL
BEGIN
RETURN @dateTime;
END
IF @startOrEnd NOT IN('Start', 'End')
BEGIN
RETURN CAST('@startOrEnd should be IN(Start, End)' AS INT);
END
/*result*/
DECLARE @result DATETIME;
SELECT @result =
CASE @startOrEnd
WHEN 'Start' THEN DATEADD(DAY, DATEDIFF(DAY, 0, @dateTime), 0)
WHEN 'End' THEN DATEADD(SECOND, -1, _
DATEADD(DAY, DATEDIFF(DAY, 0, @dateTime) + 1, 0))
END;
RETURN @result;
END
Using Function
Hide
DECLARE @dateTime DATETIME ='2019-12-01 17:20:00' /*yyyy-MM-dd HH:mm:ss*/
SELECT
[DateTime] = @dateTime,
[StartDateTime] = dbo.DateTimePart(@dateTime, 'start'),
[EndDateTime] = dbo.DateTimePart(@dateTime, 'end');
Others
DateTime Now
Hide
SELECT
[Local] = GETDATE(),
[Utc] = GETUTCDATE();
DateTime To Date
Hide
SELECT
[Date] = CONVERT(DATE, GETDATE()), --CONVERT(DATE, GETDATE(), 101)
[Date] = CAST(GETDATE() AS DATE),
[DateTime] = DATEADD(dd, DATEDIFF(dd, 0, GETDATE()), 0); --DAY
Day, Month, Year Detail
Name
Hide
SELECT
[Day] = DATENAME(WEEKDAY, GETDATE()),
[Month] = DATENAME(MONTH, GETDATE()),
[Year] = DATENAME(YEAR, GETDATE());
Number
Hide
SELECT
[Day] = DATEPART(WEEKDAY, GETDATE()),
[Month] = DATEPART(MONTH, GETDATE()),
[Year] = DATEPART(YEAR, GETDATE());
Add To Date
Adding a Day
Hide
SELECT
[Today] = GETDATE(),
[TodayPlusOneDayUsingFunction] = DATEADD(dd, 1, GETDATE()), /*addsing one day*/
[TodayPlusOneDayUsingOperator] = GETDATE() + 1; /*addsing one day*/
Deducing a Second
Hide
SELECT
[NowDateTime] = GETDATE(),
[StatDateTime] = DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0), /*removing time details*/
[EndDateTime] = DATEADD(SECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) + 1, 0)); /*removing time details, adding one date(+1), deducting one second(-1)*/
Deduction Millisecond
Để thêm / khấu trừ MILLISECOND / MICROSECOND / NANOSECOND, tốt hơn là truyền nguồn / kết quả cho đối tượng DATETIME2 thay vì DATETIME.
Hide
SELECT
[NowDateTime] = GETDATE(),
DATEADD(MILLISECOND, -1, DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) + 1, 0)), /*not as expected, went to next date*/
/*
MICROSECOND, MICROSECOND, NANOSECOND need DATETIME2, better to use DATETIME2 data type
Datetime2 Vs Datetime: https://stackoverflow.com/questions/1334143/datetime2-vs-datetime-in-sql-server
*/
DATEADD(MILLISECOND, -1, CAST(DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) + 1, 0) AS DATETIME2)),
DATEADD(MICROSECOND, -1, CAST(DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) + 1, 0) AS DATETIME2)),
DATEADD(NANOSECOND, -1, CAST(DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()) + 1, 0) AS DATETIME2));
Group By Date
đ
DECLARE @tblTest TABLE(AddDateTime DATETIME NOT NULL);
INSERT
INTO @tblTest
VALUES
/*yyyy-MM-dd hh:mm:ss*/
('2019-04-17 03:20:00'),
('2019-04-17 04:20:00'),
('2019-04-16 03:20:00'),
('2019-04-16 04:20:00')
SELECT
[Date] = DATEADD(dd, DATEDIFF(dd, 0, AddDateTime), 0),
[Total] = COUNT(AddDateTime)
FROM @tblTest
GROUP BY DATEADD(dd, DATEDIFF(dd, 0, AddDateTime), 0);
Reference:https://www.codeproject.com/Articles/5161688/SQL-Server-DateTime-Range-Pro
Nhận xét
Đăng nhận xét