Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

Truy vấn MySQL cho phạm vi ngày nhất định

Thật ngạc nhiên là không ai nhận ra điều này trong gần hai năm, nhưng các câu trả lời khác đều sai bởi vì họ đã không tính đến trường hợp cả ngày bắt đầu và ngày kết thúc đều nằm ngoài phạm vi phạm vi tìm kiếm. Hãy coi đây là phạm vi ngày:

start_date <<---------------------------- date range --------------------------->> end_date

Và đây là phạm vi tìm kiếm của chúng tôi:

start_date <<---------------------------- date range --------------------------->> end_date

                 start_search <<-------- search range -------->> end_search

Việc tìm kiếm sẽ cho chúng ta một kết quả tích cực vì chúng giao nhau. Nhưng nếu bạn sử dụng các câu trả lời khác, bạn sẽ nhận được kết quả âm vì cả start_date cũng không phải end_date nằm giữa start_searchend_search .

Để có giải pháp, hãy vẽ tất cả 4 chế độ có thể có giao lộ:

                  start_date <<---------- date range --------------------------->> end_date

start_search <<------------------------- search range -------->> end_search
start_date <<---------------------------- date range ---------->> end_date

               start_search <<---------- search range ------------------------>> end_search
start_date <<---------------------------- date range --------------------------->> end_date

                 start_search <<-------- search range -------->> end_search
                 start_date <<----------- date range -------->> end_date

start_search <<------------------------- search range ------------------------>> end_search

Bạn có thể OR cả 4 trường hợp có thể xảy ra để có được giải pháp đơn giản:

select*from table where

   /* 1st case */ start_date between start_search and end_search         
or /* 2nd case */  end_date  between start_search and end_search         
or /* 3rd case */ (start_date <= start_search and end_date >= end_search)
or /* 4th case */ (start_date >= start_search and end_date <= end_search)

/* the 4th case here is actually redundant since it is being covered by the 1st and 2nd cases */

Một giải pháp ít đơn giản hơn là:

select*from table where

    start_date  between start_search and end_search /* covers 1st and 4th cases */          
or start_search between  start_date  and  end_date  /* covers 2nd and 3rd cases */

Hãy thử hình dung nó bằng cách sử dụng các sơ đồ trên.

Nếu chúng ta cố gắng ngoại suy một mẫu trong số 4 sơ đồ ở trên, chúng ta có thể thấy rằng trong một giao lộ, end_date luôn là >= start_search và mặt khác, start_date luôn là <= end_search . Thật vậy, hình dung sâu hơn, chúng ta có thể thấy rằng khi hai điều kiện đó giữ nguyên, chúng ta không thể không có giao điểm .

Như vậy, một giải pháp khác cũng đơn giản như:

select*from table where

end_date >= start_search && start_date <= end_search

Và ưu điểm của giải pháp này là chúng ta chỉ cần 2 phép so sánh. Ngược lại với "OR mọi thứ "phương pháp tiếp cận yêu cầu từ 2 đến tối đa 8 (3 &cộng; 3 &cộng; 2) so sánh. (Mỗi between cuộc gọi bao gồm 3 phép so sánh .)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Ai đó đã hack cơ sở dữ liệu của tôi - làm thế nào?

  2. Dấu thời gian và ngày tháng trong một hàng bảng MySQL

  3. Neo4j - Tạo nút bằng Cypher

  4. Chèn vào nhiều bảng trong một truy vấn

  5. CHAR () hoặc VARCHAR () làm khóa chính trong bảng ISAM MySQL?