Cách tốt nhất để cắt ngắn một giá trị thời gian (như loại bỏ giờ phút và giây) trong SQL Server 2008 là gì?
Ví dụ:
declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)
-----------------------
2009-05-28 00:00:00.000
Cách tốt nhất để cắt ngắn một giá trị thời gian (như loại bỏ giờ phút và giây) trong SQL Server 2008 là gì?
Ví dụ:
declare @SomeDate datetime = '2009-05-28 16:30:22'
select trunc_date(@SomeDate)
-----------------------
2009-05-28 00:00:00.000
Câu trả lời:
Điều này tiếp tục thường xuyên thu thập thêm phiếu bầu, thậm chí vài năm sau đó, và vì vậy tôi cần cập nhật nó cho các phiên bản hiện đại của Sql Server. Đối với Sql Server 2008 trở lên, thật đơn giản:
cast(getDate() As Date)
Lưu ý rằng ba đoạn cuối gần phía dưới vẫn được áp dụng và bạn thường cần lùi lại một bước và tìm cách tránh diễn viên ở vị trí đầu tiên.
Nhưng có nhiều cách khác để thực hiện điều này, quá. Dưới đây là những phổ biến nhất.
Cách chính xác (mới kể từ Sql Server 2008):
cast(getdate() As Date)
Cách chính xác (cũ):
dateadd(dd, datediff(dd,0, getDate()), 0)
Bây giờ nó đã cũ hơn, nhưng nó vẫn đáng để biết vì nó cũng có thể dễ dàng thích nghi với các thời điểm khác, như khoảnh khắc đầu tiên của tháng, phút, giờ hoặc năm.
Cách chính xác này sử dụng các chức năng được ghi lại là một phần của tiêu chuẩn ansi và được đảm bảo để hoạt động, nhưng nó có thể chậm hơn một chút. Nó hoạt động bằng cách tìm xem có bao nhiêu ngày từ ngày 0 đến ngày hiện tại và thêm nhiều ngày trở lại ngày 0. Nó sẽ hoạt động bất kể thời gian của bạn được lưu trữ như thế nào và bất kể địa điểm của bạn là gì.
Cách nhanh chóng:
cast(floor(cast(getdate() as float)) as datetime)
Điều này hoạt động vì các cột datetime được lưu trữ dưới dạng giá trị nhị phân 8 byte. Truyền cho chúng nổi, đặt sàn để loại bỏ phân số và phần thời gian của các giá trị sẽ biến mất khi bạn chuyển chúng trở lại datetime. Tất cả chỉ là một chút thay đổi mà không có logic phức tạp và nó rất nhanh.
Xin lưu ý rằng điều này phụ thuộc vào chi tiết triển khai Microsoft có thể thay đổi bất cứ lúc nào, ngay cả trong bản cập nhật dịch vụ tự động. Nó cũng không di động lắm. Trong thực tế, việc triển khai này rất khó có thể sớm thay đổi, nhưng điều quan trọng là phải nhận thức được sự nguy hiểm nếu bạn chọn sử dụng nó. Và bây giờ chúng ta có tùy chọn để chọn một ngày, điều đó hiếm khi cần thiết.
Cách sai:
cast(convert(char(11), getdate(), 113) as datetime)
Cách sai hoạt động bằng cách chuyển đổi thành một chuỗi, cắt ngắn chuỗi và chuyển đổi lại thành một datetime. Điều đó là sai , vì hai lý do: 1) nó có thể không hoạt động trên tất cả các địa phương và 2) đó là cách chậm nhất có thể để làm điều này ... và không chỉ một chút; nó giống như một thứ tự cường độ hoặc chậm hơn hai so với các tùy chọn khác.
Cập nhật Điều này đã nhận được một số phiếu gần đây và vì vậy tôi muốn thêm vào đó vì kể từ khi tôi đăng bài này, tôi đã thấy một số bằng chứng khá chắc chắn rằng Sql Server sẽ tối ưu hóa sự khác biệt hiệu suất giữa cách "chính xác" và cách "nhanh" , có nghĩa là bây giờ bạn nên ủng hộ trước đây.
Trong cả hai trường hợp, bạn muốn viết các truy vấn của mình để tránh phải làm điều này ngay từ đầu . Rất hiếm khi bạn làm công việc này trên cơ sở dữ liệu.
Ở hầu hết các nơi, cơ sở dữ liệu đã là nút cổ chai của bạn. Nói chung, máy chủ đắt nhất để thêm phần cứng để cải thiện hiệu suất và là máy chủ khó nhất để có được những bổ sung đó (ví dụ: bạn phải cân bằng đĩa với bộ nhớ). Đó cũng là khó khăn nhất để mở rộng ra bên ngoài, cả về mặt kỹ thuật và từ quan điểm kinh doanh; Về mặt kỹ thuật, việc thêm một máy chủ ứng dụng hoặc web dễ dàng hơn nhiều so với máy chủ cơ sở dữ liệu và ngay cả khi đó là sai, bạn không phải trả 20.000 đô la cho mỗi giấy phép máy chủ cho IIS hoặc apache.
Điểm tôi đang cố gắng thực hiện là bất cứ khi nào có thể bạn nên thực hiện công việc này ở cấp ứng dụng. Lần duy nhất bạn nên thấy mình cắt ngắn một datetime trên Sql Server là khi bạn cần nhóm theo ngày và thậm chí sau đó bạn có thể nên có một cột bổ sung được thiết lập dưới dạng cột được tính toán, duy trì tại thời điểm chèn / cập nhật hoặc duy trì trong logic ứng dụng. Lấy công việc nặng về chỉ số, cpu này ra khỏi cơ sở dữ liệu của bạn.
cast(getdate() as date)
?
getdate()
đây là điểm thay thế cho bất kỳ nguồn thời gian nào bạn có thể có.
Chỉ dành cho SQL Server 2008
CAST(@SomeDateTime AS Date)
Sau đó chuyển nó trở lại datetime nếu bạn muốn
CAST(CAST(@SomeDateTime AS Date) As datetime)
Chỉ vì một câu trả lời đầy đủ hơn, đây là một cách làm việc để cắt bớt bất kỳ phần nào trong ngày và bao gồm cả phút (thay thế GETDATE()
bằng ngày để cắt ngắn).
Điều này khác với câu trả lời được chấp nhận ở chỗ bạn có thể sử dụng không chỉ dd
(ngày), mà bất kỳ phần nào trong ngày (xem tại đây ):
dateadd(minute, datediff(minute, 0, GETDATE()), 0)
Lưu ý rằng trong biểu thức trên, 0
là một ngày không đổi vào đầu năm (1900-01-01). Nếu bạn cần cắt ngắn thành các phần nhỏ hơn, chẳng hạn như giây hoặc mili giây, bạn cần lấy một ngày không đổi gần với ngày bị cắt bớt để tránh tràn.
dateadd(minute, datediff(minute, 0, GETDATE()) / 15 * 15, 0)
Đoạn mã tôi tìm thấy trên web khi tôi phải làm điều này là:
dateadd(dd,0, datediff(dd,0, YOURDATE))
e.g.
dateadd(dd,0, datediff(dd,0, getDate()))
DateAdd(dd, DateDiff(...), 0)
. Điều này có thể cắn bạn nếu bạn không cẩn thận.
Trong SQl 2005, hàm trunc_date của bạn có thể được viết như thế này.
(1)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
CAST(FLOOR( CAST( @date AS FLOAT ) )AS DATETIME)
END
Phương pháp đầu tiên sạch sẽ hơn nhiều. Nó chỉ sử dụng 3 lệnh gọi phương thức bao gồm CAST () cuối cùng và không thực hiện nối chuỗi, đây là một phép cộng tự động. Hơn nữa, không có loại phôi lớn ở đây. Nếu bạn có thể tưởng tượng rằng tem Ngày / Giờ có thể được biểu diễn, thì chuyển đổi từ ngày sang số và quay lại ngày là một quá trình khá dễ dàng.
(2)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CONVERT(varchar, @date,112)
END
Nếu bạn lo lắng về việc triển khai datetimes (2) hoặc (3) của microsoft có thể ổn.
(3)
CREATE FUNCTION trunc_date(@date DATETIME)
RETURNS DATETIME
AS
BEGIN
SELECT CAST((STR( YEAR( @date ) ) + '/' +STR( MONTH( @date ) ) + '/' +STR( DAY(@date ) )
) AS DATETIME
END
Thứ ba, phương pháp dài dòng hơn. Điều này đòi hỏi phải chia ngày thành các phần năm, tháng và ngày của nó, đặt chúng lại với nhau theo định dạng "yyyy / mm / dd", sau đó chuyển ngày đó trở lại. Phương thức này bao gồm 7 lệnh gọi phương thức bao gồm CAST () cuối cùng, chưa kể đến nối chuỗi.
CONVERT(DATE, <yourdatetime>) or CONVERT(DATE, GetDate()) or CONVERT(DATE, CURRENT_TIMESTAMP)
chọn cast (floor (cast (getdate () as float)) làm datetime) Tham khảo cái này: http://microsoftmiles.blogspot.com/2006/11/remove-time-from-datetime-in-sql-server.html
Đối với những người bạn đến đây đang tìm cách cắt ngắn trường DATETIME thành một thứ ít hơn cả ngày, ví dụ mỗi phút, bạn có thể sử dụng cách này:
SELECT CAST(FLOOR(CAST(GETDATE() AS FLOAT)) + (FLOOR((CAST(GETDATE() AS FLOAT) - FLOOR(CAST(GETDATE() AS FLOAT))) * 1440.0) + (3.0/86400000.0)) / 1440.0 AS DATETIME)
Vì vậy, nếu hôm nay là 2010-11-26 14:54:43.123
sau này sẽ trở lại 2010-11-26 14:54:00.000
.
Để thay đổi khoảng thời gian mà nó thực hiện, thay thế 1440.0 bằng số lượng khoảng thời gian trong một ngày, ví dụ:
24hrs = 24.0 (for every hour)
24hrs / 0.5hrs = 48.0 (for every half hour)
24hrs / (1/60) = 1440.0 (for every minute)
(Luôn đặt .0
dấu chấm hết để hoàn toàn thả nổi.)
Đối với những người bạn tự hỏi những gì (3.0/86400000)
là cho trong tính toán của tôi, SQL Server 2005 dường như không diễn viên từ FLOAT
đến DATETIME
một cách chính xác, vì vậy đây thêm 3 mili giây trước khi sàn nó.
datetime2
kiểu dữ liệu.
Truy vấn này sẽ cung cấp cho bạn kết quả tương đương với trunc(sysdate)
trong Oracle.
SELECT *
FROM your_table
WHERE CONVERT(varchar(12), your_column_name, 101)
= CONVERT(varchar(12), GETDATE(), 101)
Hi vọng điêu nay co ich!
Bạn cũng có thể trích xuất ngày using Substring
từ biến datetime và chuyển trở lại datetime sẽ bỏ qua phần thời gian.
declare @SomeDate datetime = '2009-05-28 16:30:22'
SELECT cast(substring(convert(varchar(12),@SomeDate,111),0,12) as Datetime)
Ngoài ra, bạn có thể truy cập các phần của biến datetime và hợp nhất chúng vào một ngày rút ngắn cấu trúc, đại loại như thế này:
SELECT cast(DATENAME(year, @Somedate) + '-' +
Convert(varchar(2),DATEPART(month, @Somedate)) + '-' +
DATENAME(day, @Somedate)
as datetime)
bạn có thể làm điều này (SQL 2008):
khai báo @SomeDate ngày = getdate ()
select @SomeDate
2009-05-28
TRUNC (aDate, 'DD') sẽ cắt bớt phút, giây và giờ
SRC: http://www.techonthenet.com/oracle/fifts/trunc_date.php