Chuyển đến nội dung chính

HÀM SQL DATEDIFF()

DATEDIFF() là một trong những hàm thao tác dữ liệu ngày tháng dùng nhiều nhất trong SQL. Hãy đọc hướng dẫn này để nắm vững.
· 3 phút đọc

Khám phá cùng AI

DATEDIFF() là một trong những hàm thao tác ngày giờ được dùng rộng rãi nhất trong SQL. Hướng dẫn này sẽ đưa bạn qua cách sử dụng, cú pháp và các khác biệt chính giữa các biến thể SQL phổ biến, giúp bạn làm chủ hàm mạnh mẽ này.

Hàm DATEDIFF() là gì?

Hàm DATEDIFF() tính chênh lệch giữa hai giá trị ngày hoặc timestamp và trả về kết quả theo một đơn vị xác định, như ngày, tháng hoặc năm.

Cú pháp DATEDIFF theo các biến thể SQL

Cú pháp của DATEDIFF() khác nhau giữa các biến thể SQL. Dưới đây là ví dụ cho các hệ quản trị cơ sở dữ liệu thường dùng:

 

Dưới đây là bài viết đã được cập nhật và chỉnh lý đầy đủ với mọi cải tiến được yêu cầu:


Hàm SQL DATEDIFF()

DATEDIFF() là một trong những hàm thao tác ngày giờ được dùng rộng rãi nhất trong SQL. Hướng dẫn này sẽ đưa bạn qua cách sử dụng, cú pháp và các khác biệt chính giữa các biến thể SQL phổ biến, giúp bạn làm chủ hàm mạnh mẽ này.


Hàm DATEDIFF() là gì?

Hàm DATEDIFF() tính chênh lệch giữa hai giá trị ngày hoặc timestamp và trả về kết quả theo một đơn vị xác định, như ngày, tháng hoặc năm.


Cú pháp DATEDIFF theo các biến thể SQL

Cú pháp của DATEDIFF() khác nhau giữa các biến thể SQL. Dưới đây là ví dụ cho các hệ quản trị cơ sở dữ liệu thường dùng:

SQL Server

DATEDIFF(datepart, startdate, enddate)
  • datepart: Đơn vị thời gian (ví dụ: year, month, day).
  • startdate và enddate: Các ngày hoặc timestamp để so sánh. Kết quả được tính là enddate - startdate.

MySQL

DATEDIFF(enddate, startdate)
  • Chỉ trả về chênh lệch theo ngày.

PostgreSQL

PostgreSQL không có hàm DATEDIFF() nhưng cung cấp chức năng tương tự thông qua:

  • Hàm AGE():
SELECT AGE(enddate, startdate);
  • Trừ trực tiếp các giá trị ngày:
SELECT enddate - startdate;

Tham số

Đó là gì?

datepart

Một tham số bắt buộc. Đây là đơn vị mà DATEDIFF() dùng để trả về chênh lệch giữa startdate và enddate. Xem mục tiếp theo để biết các giá trị có thể nhận. 

startdate

Một tham số bắt buộc biểu thị giá trị datetime dùng làm ngày bắt đầu. 

enddate

Một tham số bắt buộc biểu thị giá trị datetime dùng làm ngày kết thúc. 

Cú pháp datepart 

Tham số datepart xác định đơn vị thời gian để tính chênh lệch. SQL Server hỗ trợ các giá trị datepart sau:

DatepartBí danh
yearyy, yyyy
quarterqq, q
monthmm, m
daydd, d
hourhh
minutemi, n
secondss, s
millisecondms

Lưu ý: MySQL chỉ hỗ trợ day làm đơn vị thời gian cho DATEDIFF().

  • Dấu nháy: Luôn dùng dấu nháy đơn (') cho giá trị ngày giờ.
  • Kết quả âm/dương: Trong SQL Server, kết quả dương khi enddate > startdate và âm nếu ngược lại.
  • Xử lý lỗi: Nếu kết quả vượt quá ±2.147.483.647, hãy dùng DATEDIFF_BIG() trong SQL Server.

Ví dụ về DATEDIFF()

Khi dùng DATEDIFF(), kết quả có thể là giá trị dương hoặc âm. Nếu enddate muộn hơn startdate, DATEDIFF() trả về giá trị dương. Nếu enddate sớm hơn startdate, DATEDIFF() trả về giá trị âm. 

Ví dụ 1: Tìm chênh lệch giữa hai ngày

Trong SQL Server:

SELECT DATEDIFF(year, '2022-12-31', '2024-06-01') AS years_difference;

Giải thích: Câu lệnh này tính chênh lệch theo năm giữa hai ngày. Vì tính các năm 2023 và một phần 2024, kết quả là 1.

Trong MySQL: 

SELECT DATEDIFF('2024-06-01', '2022-12-31') AS days_difference;

Giải thích: MySQL chỉ hỗ trợ chênh lệch theo ngày. Kết quả là 518.

Ví dụ 2: Tìm chênh lệch giữa hai timestamp

SELECT 
    DATEDIFF(hour, '2023-12-31 00:00:00', '2023-12-31 23:59:59') AS hours_difference,
    DATEDIFF(minute, '2023-12-31 00:00:00', '2023-12-31 23:59:59') AS minutes_difference,
    DATEDIFF(second, '2023-12-31 00:00:00', '2023-12-31 23:59:59') AS seconds_difference;

Giải thích:

  • hours_difference trả về 23 vì hai timestamp cách nhau 23 giờ.
  • minutes_difference trả về 1439, tức 23 hours * 60 minutes.
  • seconds_difference trả về 86,399, tức 1439 minutes * 60 seconds.

Ví dụ 3: Tìm chênh lệch giữa hai cột ngày

Giả sử bạn có bảng orders với order_date và shipped_date. Hãy dùng DATEDIFF() để tính thời gian giao hàng cho từng đơn.

SELECT 
    order_id,
    DATEDIFF(day, order_date, shipped_date) AS shipping_days 
FROM sales.orders;

Giải thích: Truy vấn tính số ngày cần để giao mỗi đơn hàng.

Ví dụ 4. Tìm khoảng cách giữa ngày hôm nay và một cột

Vẫn dùng bảng sales.orders như ở Ví dụ 3, ta có thể dùng DATEDIFF() để tìm khoảng cách giữa ngày hôm nay và ngày đặt hàng.

SELECT 
    order_id,
    order_date,
    GETDATE() AS today_date,
    DATEDIFF(day, order_date, GETDATE()) AS days_from_order;

Giải thích:

  • GETDATE() lấy ngày giờ hiện tại trong SQL Server.
  • Tính chênh lệch theo ngày từ order_date đến hôm nay.

Ghi chú bổ sung

Hàm DATEDIFF() trả về lỗi nếu kết quả vượt phạm vi (tức giá trị lớn hơn +2.147.483.647 hoặc nhỏ hơn -2.147.483.647). Khi đó, hãy dùng hàm DATEDIFF_BIG(). 

Lỗi thường gặp và cách khắc phục

Khi làm việc với DATEDIFF(), bạn có thể dễ gặp lỗi về cú pháp, thứ tự đối số hoặc hành vi đặc thù theo cơ sở dữ liệu. Dưới đây là các lỗi phổ biến và cách xử lý:

1. Dấu nháy không đúng

Vấn đề: Dùng dấu nháy quanh datepart hoặc không nhất quán khi đặt dấu nháy cho literal ngày.

Giải pháp: Luôn để datepart không có dấu nháy và dùng nháy đơn cho ngày.

-- Incorrect
SELECT DATEDIFF('year', '2023-01-01', '2024-01-01');

-- Correct
SELECT DATEDIFF(year, '2023-01-01', '2024-01-01');
 

2. datepart không được hỗ trợ trong MySQL

Vấn đề: DATEDIFF() của MySQL chỉ hỗ trợ chênh lệch theo ngày.

Giải pháp: Dùng TIMESTAMPDIFF() cho các đơn vị chi tiết như năm hoặc tháng.

-- Correct (MySQL)
SELECT TIMESTAMPDIFF(YEAR, '2023-01-01', '2024-01-01') AS years_difference; -- Returns 1

3. Thứ tự đối số rất quan trọng

Vấn đề: Đảo startdate và enddate có thể dẫn đến kết quả âm ngoài ý muốn.

Giải pháp: Đảm bảo startdate đứng trước. Dùng ABS() nếu chỉ quan tâm độ lớn.

-- Incorrect
SELECT DATEDIFF(day, '2023-01-05', '2023-01-01'); -- Returns -4

-- Correct
SELECT DATEDIFF(day, '2023-01-01', '2023-01-05'); -- Returns 4

4. Định dạng ngày theo địa phương

Vấn đề: Định dạng mơ hồ (ví dụ MM/DD/YYYY so với DD/MM/YYYY) có thể gây lỗi.

Giải pháp: Dùng chuẩn ISO 8601 (YYYY-MM-DD) để tránh mơ hồ.

-- Correct
SELECT DATEDIFF(day, '2023-01-01', '2023-12-31'); -- Returns 364

5. Giá trị vượt phạm vi (SQL Server)

Vấn đề: Chênh lệch lớn vượt ±2.147.483.647 gây lỗi tràn. Giải pháp: Dùng DATEDIFF_BIG() cho khoảng rất lớn.

-- Correct
SELECT DATEDIFF_BIG(day, '0001-01-01', '9999-12-31'); -- Returns 2,920,862,800

Yêu cầu kỹ thuật

Hoạt động trên SQL Server (từ 2008), Azure SQL Database, Azure SQL Data Warehouse, Parallel Data Warehouse

Xem thêm

Tìm hiểu thêm về SQL

Travis Tang

Tác giả

Travis Tang

Là một nhà khoa học dữ liệu tại Tiktok và học viên cao học tại GeorgiaTech, tôi có niềm đam mê bẩm sinh với khoa học dữ liệu và đã tạo dựng một con đường sự nghiệp độc đáo, đan xen giữa công nghệ, rủi ro và cải thiện bản thân không ngừng. Trong thời gian làm Nhà khoa học dữ liệu tại Merchant Platform, tôi đã giảm thiểu rủi ro và chống gian lận bằng các mô hình dữ liệu phức tạp, giúp tiết kiệm hàng nghìn đô la mỗi tuần. Tôi mài giũa chuyên môn của mình bằng vô số giờ tự học, nhận chứng chỉ từ các tổ chức uy tín và thành thạo các chủ đề như Học sâu, TensorFlow và Phân tích mạng xã hội. Trên DataCamp và các nền tảng giáo dục khác, tôi tận dụng kho tri thức này để truyền cảm hứng và giáo dục mọi người, mở ra những lối đi mới trong lĩnh vực khoa học dữ liệu và chứng minh rằng với quyết tâm và dữ liệu phù hợp, mọi rủi ro đều có thể biến thành cơ hội.

Chủ đề

Liên quan