So sánh thời gian của MySQL trong mệnh đề WHERE

Trong hướng dẫn này, bạn đã tìm hiểu về kiểu dữ liệu

CREATE TABLE timestamp_n_datetime ( id INT AUTO_INCREMENT PRIMARY KEY, ts TIMESTAMP, dt DATETIME );

Code language: SQL (Structured Query Language) (sql)0 của MySQL và một số hàm

CREATE TABLE timestamp_n_datetime ( id INT AUTO_INCREMENT PRIMARY KEY, ts TIMESTAMP, dt DATETIME );

Code language: SQL (Structured Query Language) (sql)0 hữu ích
Một giá trị ngày, giờ hoặc dấu thời gian có thể được so sánh với một giá trị khác của cùng một loại dữ liệu, một hằng số ngày giờ của cùng một loại dữ liệu hoặc với một biểu diễn chuỗi của một giá trị của loại dữ liệu đó. Ngoài ra, giá trị DẤU THỜI GIAN KHÔNG CÓ Múi giờ có thể được so sánh với giá trị DẤU THỜI GIAN CÓ Múi giờ

Tất cả các so sánh đều theo trình tự thời gian, có nghĩa là thời điểm càng xa từ ngày 1 tháng 1 năm 0001 thì giá trị của thời điểm đó càng lớn. Thời gian 24. 00. 00 so sánh lớn hơn thời gian 00. 00. 00

So sánh liên quan đến giá trị THỜI GIAN và biểu diễn chuỗi giá trị thời gian luôn bao gồm giây. Nếu biểu diễn chuỗi bỏ qua giây, thì không có giây nào được ngụ ý

Các so sánh liên quan đến giá trị dấu thời gian được đánh giá theo các quy tắc sau

  • Khi so sánh các giá trị dấu thời gian với các độ chính xác khác nhau, độ chính xác cao hơn được sử dụng để so sánh và mọi chữ số bị thiếu trong giây phân số được coi là bằng không
  • Khi so sánh giá trị DẤU THỜI GIAN CÓ Múi giờ với giá trị DẤU THỜI GIAN KHÔNG CÓ Múi giờ, giá trị DẤU THỜI GIAN KHÔNG CÓ Múi giờ được chuyển thành DẤU THỜI GIAN CÓ Múi giờ trước khi so sánh được thực hiện
  • Khi so sánh hai giá trị DẤU THỜI GIAN VỚI Múi giờ, việc so sánh được thực hiện bằng cách sử dụng biểu diễn UTC của các giá trị. Hai giá trị DẤU THỜI GIAN VỚI Múi giờ được coi là bằng nhau nếu chúng đại diện cho cùng một phiên bản trong UTC, bất kể độ lệch múi giờ được lưu trữ trong các giá trị. Ví dụ: '1999-04-15-08. 00. 00-08. 00' (8. 00 một. m. Giờ chuẩn Thái Bình Dương) giống như '1999-04-15-11. 00. 00-05. 00' (11. 00 một. m. Giờ chuẩn phương Đông)
  • Khi so sánh giá trị dấu thời gian với biểu diễn chuỗi của dấu thời gian, biểu diễn chuỗi trước tiên được chuyển thành kiểu dữ liệu của toán hạng dấu thời gian. Ngoại trừ giá trị được chuyển đổi có độ chính xác là 12. Nếu toán hạng dấu thời gian là DẤU THỜI GIAN KHÔNG CÓ Múi giờ, thì chuỗi không được chứa thông số múi giờ
  • So sánh dấu thời gian là theo trình tự thời gian mà không tính đến các biểu diễn có thể được coi là tương đương. Ví dụ, vị từ sau đây là đúng. TIMESTAMP('1990-02-23-00.00.00') > '1990-02-22-24.00.00'

ví dụ 1. Bảng TABLE1 có 2 cột. C1, được định nghĩa là DẤU THỜI GIAN VỚI Múi giờ; . CREATE TABLE TABLE1 (C1 TIMESTAMP WITH TIME ZONE, C2 TIMESTAMP);Một hàng được chèn vào bảng với câu lệnh INSERT sau. Các giá trị đầu vào được cung cấp bởi các biểu diễn chuỗi ký tự của dấu thời gian với múi giờ. INSERT INTO TABLE1 VALUES ( '2007-11-05-08.00.00-08:00', '2007-11-05-08.00.00');Giả sử rằng múi giờ ngầm định là -5:00, câu lệnh SELECT sau đây sẽ không trả về bất kỳ hàng nào. Biểu diễn chuỗi của giá trị DẤU THỜI GIAN KHÔNG CÓ Múi giờ được chuyển thành giá trị DẤU THỜI GIAN CÓ Múi giờ, dẫn đến dấu thời gian có giá trị múi giờ là '2007-11-05-08.00.00-05:00' cho cột C2. Vị từ so sánh là sai vì hai giá trị không bằng nhau. SELECT 1 FROM TABLE1 WHERE C1 = C2;

ví dụ 2. Khi giá trị DẤU THỜI GIAN KHÔNG CÓ Múi giờ được so sánh với một biểu diễn chuỗi của DẤU THỜI GIAN KHÔNG CÓ Múi giờ hoặc giá trị DẤU THỜI GIAN CÓ Múi giờ, thì biểu diễn chuỗi được chuyển thành DẤU THỜI GIAN KHÔNG CÓ Múi giờ (bất kể chuỗi có chứa múi giờ hay không). Việc so sánh được thực hiện bằng cách sử dụng hai giá trị DẤU THỜI GIAN KHÔNG CÓ Múi giờ. Giả sử rằng string_hv chứa dấu thời gian có giá trị múi giờ là '2007-11-05-08.00.00-08:00'. Giá trị chuỗi được chuyển thành giá trị DẤU THỜI GIAN KHÔNG CÓ Múi giờ của '2007-11-05-08.00.00', giá trị này được so sánh với giá trị được lưu trữ trong cột C2. Câu lệnh SELECT sau đây trả về một hàng đơn vì một hàng tồn tại trong bảng có dấu thời gian không có giá trị múi giờ là '2007-11-05-08.00.00'. SELECT 1 FROM TABLE1 WHERE C2 = :string_hv;

Thật khó để sử dụng ngày tháng trong truy vấn máy chủ SQL, đặc biệt nếu bạn không có kiến ​​thức tốt về cách thức hoạt động của loại DateTime trong máy chủ SQL. Ví dụ: một trong những truy vấn SQL thường được hỏi trong cuộc phỏng vấn là "chọn tất cả các hàng có ngày là 20151007?"

chọn * từ bảng trong đó ngày = '20151007'

Có thể có hoặc không, hoàn toàn phụ thuộc vào dữ liệu trong bảng của bạn. Khi bạn chỉ cung cấp phần ngày của biến DateTime, nó sẽ sử dụng '00. 00. 00. 000' cho phần thời gian.

Vì vậy, nếu bạn có bất kỳ hàng nào có cùng ngày nhưng khác giờ thì truy vấn này sẽ không hoạt động. Ví dụ: bạn có bảng Đơn hàng nơi bạn có hai đơn hàng, một đơn hàng có order_date='20150107' và đơn hàng khác có order_date='20150107:01:00:00:000' , thì truy vấn trên sẽ chỉ trả về đơn đặt hàng đầu tiên. Tôi sẽ giải thích cách tìm các hàng giữa các ngày trong SQL Server chi tiết hơn trong bài viết này.

Nhiều lập trình viên Java hoặc C++ sử dụng SQL Server không chú ý đầy đủ đến kiểu dữ liệu của cột ngày tháng e. g. order_date, trade_date, v.v. và nhiều người trong số họ thậm chí không biết rằng SQL Server sẽ so sánh tình trạng của họ với dữ liệu trong cột đó như thế nào. Không có gì ngạc nhiên vì đối với họ SQL là kỹ năng phụ, trong khi C++ hoặc Java là kỹ năng chính, nhưng thành thật mà nói sẽ có rất ít ứng dụng trong thế giới thực mà bạn không phải làm việc trên SQL

Vì vậy, nếu bạn muốn nâng cao kiến ​​thức của mình về các nguyên tắc cơ bản của SQL, đặc biệt là trong SQL Server, tôi khuyên bạn nên tham gia Microsoft SQL dành cho người mới bắt đầu để tìm hiểu thêm về các loại dữ liệu NGÀY, GIỜ và DATETIME. Tôi đã tham khảo cuốn sách đó trước khi viết bài này và nó đã giúp tôi rất nhiều trong việc lấp đầy lỗ hổng kiến ​​thức của mình




Truy vấn so sánh ngày trong SQL

Để hiểu cách so sánh ngày tháng trong SQL, hãy xem một ví dụ trong đó trường DateTime cũng có một số giá trị thời gian

Giả sử chúng ta có bảng sau với varchar course_namedatetime course_date columns:

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');
Bây giờ, bạn cần viết một truy vấn để nhận tất cả các khóa học vào ngày '2015-10-07'?

________số 8_______
Hãy xem giải pháp khác hoạt động như thế nào



Nếu bạn chỉ so sánh ngày với toán tử = và chỉ cung cấp ngày, bạn sẽ nhận được các hàng có trường thời gian bằng 0 vì máy chủ SQL sẽ sử dụng '00. 00. 00. 000" cho thời gian, như trong ví dụ sau.

SELECT * FROM #Course WHERE course_date = '2015-10-07' course_name course_date MySQL 2015-10-07 00:00:00.000
Bạn có thể thấy nó chỉ mang lại một hàng, trong đó thời gian bằng 0, nó không khớp với hai hàng khác khi thời gian khác không. Xem Truy vấn Microsoft SQL Server 2012 để tìm hiểu thêm về cách máy chủ SQL xử lý các định dạng ngày và thông tin ngày và giờ bị thiếu



Giải pháp 2 - So sánh ngày với mệnh đề between

Có vẻ như  giữa là tùy chọn phù hợp để so sánh các ngày không tính thời gian. Bạn có thể đặt ngày hiện tại và ngày tiếp theo để bao gồm tất cả các thời điểm có ngày giống nhau, nhưng tiếc là điều đó sẽ không hoạt động. Nó cũng sẽ lấy giá trị ngày tiếp theo như bên dưới.

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.000
Bạn có thể thấy giữa cũng được tìm nạp 2015-10-08 00. 00. 00. 000 giá trị, không mong muốn. Điều này xảy ra vì mệnh đề BETWEEN sẽ luôn kéo bất kỳ giá trị nào của ngày tiếp theo nửa đêm. Xem Truy vấn Microsoft SQL Server 2012 để tìm hiểu thêm về chủ đề này. Cuộc thảo luận cũng hợp lệ cho SQL Server 2014.


Luôn sử dụng >= và < để so sánh ngày tháng

Câu trả lời đúng là sử dụng các toán tử lớn hơn (>) và nhỏ hơn (= '2003-05-05'; Để thuận tiện, MySQL tự động chuyển đổi ngày thành số nếu ngày đó là .

Làm cách nào để so sánh hai trường ngày trong MySQL?

Để đếm sự khác biệt giữa các ngày trong MySQL, hãy sử dụng hàm DATEDIFF(ngày kết thúc, ngày bắt đầu) . Sự khác biệt giữa ngày bắt đầu và ngày kết thúc được biểu thị bằng ngày.

Chủ đề