簡體   English   中英

如何將數據庫中存儲的日期排除在一定范圍之外?

[英]How to exclude date stored in database to a range?

我的數據庫中有一個表格“ Holidays”,其中包含假期的天數范圍,該字段由兩列定義:開始和結束。

Holidays (id, name, start, end)

現在,如果要輸入兩個日期(從&到),我想列出所有不在假期中的日期。

假設假期為2012/06/052012/06/20 ,我要求:

  1. 從= 2012/06/01,到= 2012/06/10; 結果將是01,02,03,04
  2. 從= 2012/06/01,到= 2012/06/22; 結果將是01,02,03,04,21,22
  3. 從= 2012/06/15,到= 2012/06/22; 結果將是21,22

但是我無法弄清楚如何在不從->到范圍內請求的每一天訪問數據庫的情況下獲取“開放”天的列表。

我該怎么辦?

謝謝你的幫助!

有很多解決方案,但這很大程度上取決於數據庫中有多少個條目以及您有多少個請求。 如果您提出很多要求,那么您可以執行以下操作:

-> create a boolean array that will determine if a day is holiday or not;
   first element points to some predefined date (e.g. 1.1.2012), 
   second element to 2.1.2012, etc.
-> initialize an array to 0
-> for each holiday you do
  -> make a for loop initialized with holiday start date and
     expression for each pass: current date = holiday start date + 1 day
    -> covert the current date to index (number of days since start date - 1.1.2012)
    -> set the array[index] to 1

現在,您應該有一個簡單的數組,其中包含0(非節假日)和1(節日)

您現在為每個查詢(請求)執行的操作

-> for loop that goes from request start date to request end date
   -> convert the current date to index (number of days since 1.1.2012)
   -> check if array[index] is 0 or 1

但請注意,對於許多查詢(請求),此解決方案都是可以的。 如果必須為每個請求都做第一部分,那么此解決方案就沒有意義了,最好編寫一個sql查詢。

這是我終於做到的方法,它似乎起作用了:

SELECT start, end FROM holidays WHERE
(start > :START AND end < :END) OR
(start < :START AND end > :END) OR
(start BETWEEN :START AND :END) OR
(end BETWEEN :START AND :END);

這僅返回我的:START / :END日期接觸至少一個假期的行。 它涵蓋了這些可能性:

  1. start在假期開始之前,如果在假期結束之前(在in之前)則結束
  2. start在假期開始之前,如果在假期結束之后(之前,之后)則結束
  3. 開始是在假期開始之后,如果在假期結束之前(在,在)開始則結束
  4. 開始是在假期開始之后,如果在假期結束之后(在之后),則結束

我想我涵蓋了所有可能性。

然后,我遍歷結果並為每行構建一個從startend的日期數組。

最后,我遍歷了我的初始范圍日期,如果這些日期之一在數組中,則將其刪除。

這是一個解決方案,可以通過單個(盡管有些復雜)SQL語句(這是Oracle)為您提供解決方案:

with all_days as (
  select :start_date + (level - 1) dt
   from dual
  connect by :start_date + (level - 1) <= :end_date
)
select a.dt 
  from all_days a
 where not exists (
    select 1 
      from holidays h
     where h.start_dt <= a.dt and h.end_dt >= a.dt
)
order by a.dt

例如,假設有以下假期表:

NAME           START_DT                  END_DT                    
-------------- ------------------------- ------------------------- 
Test Holiday 1 07-JUN-12                 13-JUN-12                 
Test Holiday 2 17-JUN-12                 18-JUN-12                 

使用6月5日作為:start_date和6月20日作為:end_date ,您將獲得以下輸出:

DT                        
------------------------- 
05-JUN-12                 
06-JUN-12                 
14-JUN-12                 
15-JUN-12                 
16-JUN-12                 
19-JUN-12                 
20-JUN-12                

(提供的日期范圍減去假日表中范圍內指定的任何日期)。

希望能有所幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM