Mysql
 sql >> база данни >  >> RDS >> Mysql

MySQL заявка за определен период от време

Удивително е, че никой не е забелязал това от почти две години, но другите отговори са грешни защото не са взели предвид случая, когато и началната, и крайната дата попадат извън обхвата на диапазона на търсене. Помислете, че това е диапазонът на датата:

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

И това е диапазонът на нашето търсене:

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

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

Търсенето трябва да ни даде положителен резултат, защото се пресичат. Но ако използвате другите отговори, ще получите отрицателен резултат, защото нито start_date нито end_date е между start_search и end_search .

За да получите решението, нека нарисуваме всичките 4 възможни режима на пресичане:

                  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

Можете да OR всичките 4 възможни случая за получаване на простото решение:

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 */

По-малко просто решение е:

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 */

Опитайте се да го визуализирате с помощта на диаграмите по-горе.

Ако се опитаме да екстраполираме модел от 4-те диаграми по-горе, можем да видим, че по време на пресичане, end_date винаги е >= start_search , а от другата страна start_date винаги е <= end_search . Всъщност, визуализирайки по-нататък, можем да видим, че когато тези две условия са изпълнени, не можем да нямаме кръстовище .

Като такова, друго решение е толкова просто като:

select*from table where

end_date >= start_search && start_date <= end_search

И предимството на това решение е, че имаме нужда само от 2 сравнения. Сравнете това с „OR всичко", който изисква от 2 до 8 (3 + 3 + 2) сравнения. (Всяко between обаждането се състои от 3 сравнения .)



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Създайте вградена SQL таблица в движение (за изключващо ляво присъединяване)

  2. Получаване на всички родителски редове в една SQL заявка

  3. Как мога да заобиколя MySQL Errcode 13 с SELECT INTO OUTFILE?

  4. Как да съхранявате 128-битово число в една колона в MySQL?

  5. Ами ако имам нужда от много много голям идентификатор за автоматично увеличение?