So sánh ngày trong SQL và Sự khác nhau giữa GETDATE(), SYSDATETIME() với GETUTCDATE()

13873 lượt xem
ngôn ngữ sql là gì

Khi so sánh ngày trong SQL có khá nhiều người nhầm lẫn các câu lệnh GETDATE(), SYSDATETIME() với GETUTCDATE(). Vậy cụ thể, các câu lệnh này khác nhau như thế nào? Ý nghĩa và cách sẻ dụng mỗi câu lệnh? Hãy tìm hiểu ngay sau đây!

1. Sự khác nhau giữa GETDATE(), SYSDATETIME() với GETUTCDATE()

Trong SQL Server, cả 3 hàm GETDATE(), SYSDATETIME() với GETUTCDATE() đề dùng để trả về thời gian và ngày hiện tại nhưng chúng vẫn có những điểm khác nhau.

  • So sánh GETDATE() và SYSDATETIME():
    • GETDATE(): Trả về giá trị ngày tháng, thời gian theo kiểu DATETIME
    • SYSDATETIME(): Trả về giá trị ngày tháng, thời gian kiểu DATETIME2 chính xác hơn so với GETDATE()
  • So sánh GETDATE() và GETUTCDATE():
    • GETDATE(): Trả về ngày tháng, giờ hiện tại dựa theo múi giờ địa phương, nơi mà hệ thống server chứa CSDL đang hoạt động
    • GETUTCDATE(): Trả về ngày tháng, thời gian hiện tại dựa theo múi giờ UTC hoặc GMT
  • So sánh SYSDATETIME() và GETUTCDATE():
    • SYSDATETIME(): Trả về giá trị ngày tháng, thời gian kiểu DATETIME2
    • GETUTCDATE(): Trả về giá trị ngày tháng, thời gian kiểu DATETIME và UTC

2. Cách so sánh ngày tháng với SQL Server | Tìm tất cả bản ghi giữa 2 ngày chuẩn nhất

Khi không có kiến thức tốt về kiểu dữ liệu DATETIME thì việc so sánh ngày trong SQL sẽ tương đối khó khăn. Tuy nhiên, chúng tôi sẽ hướng dẫn bạn cách so sánh chi tiết nhất:

2.1 Câu truy vấn so sánh ngày tháng trong SQL Server

Dưới đây chúng tôi sẽ cho bạn thấy một ví dụ để hiểu rõ hơn về cách so sánh với ngày hiện tại trong SQL. Ví dụ, ta có một bảng với cột course_name định dạng kiểu VARCHAR và cột course_date định dạng kiểu DATETIME:

IF OBJECT_ID( ‘tempdb..#Course’ ) IS NOT NULL

DROP TABLE #Course;

CREATE TABLE #Course (course_name varchar(10), course_date datetime);

INSERT INTO #Course VALUES (‘Java’, ‘2015-10-06 11:16:10.496’);

INSERT INTO #Course VALUES (‘MySQL’, ‘2015-10-07 00:00:00.000’);

INSERT INTO #Course VALUES (‘SQL SERVER’, ‘2015-10-07 11:26:10.193’ );

INSERT INTO #Course VALUES (‘PostgreSQL’, ‘2015-10-07 12:36:10.393’);

INSERT INTO #Course VALUES (‘Oracle’, ‘2015-10-08 00:00:00.000’);

Ta sẽ thực hiện truy vấn để lấy toàn bộ các course vào ngày ‘2015-10-07’. Nếu truy vấn chính xác thì sẽ có kết quả 3 bản ghi sau:

‘MySQL’, ‘2015-10-07 00:00:00.000’

‘SQL SERVER’, ‘2015-10-07 11:26:10.193’

‘PostgreSQL’, ‘2015-10-07 12:36:10.393’

Trường hợp chỉ thực hiện dùng toán tử “=” để so sánh các giá trị và cung cấp ngày tháng thì kết quả nhận được sẽ là các bản ghi có phần thời gian bằng 0. Nguyên nhân là do SQL chỉ định phần thời gian là 00:00:00.000. Ví dụ:

SELECT * FROM #Course WHERE course_date = ‘2015-10-07’

course_name course_date

MySQL 2015-10-07 00:00:00.000

2.2 Giải pháp sử dụng trong so sánh ngày tháng

Để so sánh ngày tháng trong SQL server thì có thể sử dụng BETWEEN nếu không tính tới thời gian. Để phủ nhận toàn bộ thời gian trong ngày có thể đặt trong mệnh đề ngày hiện tại và ngày tiếp theo. Nhưng cách này lại không hoạt động đúng và chúng ta sẽ nhận được các bản ghi như sau:

SELECT * FROM #Course WHERE course_date between ‘2015-10-07’ and ‘2015-10-08’

course_name course_date

MySQL 2015-10-07 00:00:00.000

SQL SERVER 2015-10-07 11:26:10.193

PostgreSQL 2015-10-07 12:36:10.393

Oracle 2015-10-08 00:00:00.00

Trong bản ghi được trả về chúng ta nhận ra có giá trị 2015-10-08 00:00:00.000. Đây là kết quả không mong muốn. Vì vậy, tốt nhất là hãy sử dụng toán tử “>” và “<”. Và khi sử dụng toán tử này cần đặt mệnh đề WHERE trong cú pháp như sau:

SELECT * FROM #Course WHERE course_date >= ‘2015-10-07’ and course_date < ‘2015-10-08’

course_name course_date

MySQL 2015-10-07 00:00:00.000

SQL SERVER 2015-10-07 11:26:10.193

PostgreSQL 2015-10-07 12:36:10.393

Như vậy là các bạn sẽ nhận được các kết quả mong muốn. Hãy nhớ rằng, ở toán hạng thứ 2 đặt vào toán tử “<” để đảm bảo kết quả không trả về giá trị 2015-10-08 00:00:00.000.

3. Phần Tổng kết

  • GETDATE(): Trả về kết quả là giờ địa phương của server chứa CSDL. Giá trị được trả về kiểu DATETIME. Trường hợp đang kết nối tới 1 remote SQL server và sử dụng SQL Server Management Studio thì kết quả trả về sẽ khác với thời gian địa phương trên hệ thống
  • GETUTCDATE(): Kết quả trả về là ngày tháng, thời gian ở thời điểm hiện tại tính theo UTC hay GMT và ở dạng DATETIME
  • SYSDATETIME(): Giống GETDATE nhưng kiểu giá trị trả về lại chính xác hơn, dạng DATETIME2

Trên đây là sự khác nhau và cách sử dụng các hàm so sánh ngày trong SQL mà chúng tôi muốn chia sẻ. Hy vọng các thông tin trên hữu ích với các bạn.