2012-12-09 84 views
0

我有一個數據庫表,其中包含事件啓動時的日期。一個事件在下一個開始時結束。給定一個開始日期和結束日期,我正在尋找與他們相應的事件ID創建一個日期數組。減少這個簡單代碼的許多SQL查詢

當前我爲每個日期運行SQL查詢。僞代碼:

$currDate = $startDate 
While $currDate++ < $endDate 
    echo $currDate . " - " . dbQuery("SELECT TOP 1 ID FROM events WHERE eventDate <= '$currDate' ORDER BY eventDate DESC"); 
Loop 

我該如何讓這個效率更高(在PHP中)?

編輯:感謝您的答案,但我意識到這個問題並不清楚。管理編寫一些在我的服務器上跨越數年的日期執行快速(< 10毫秒)的SQL。

回答

0

下面是使用SQL的解決方案:

SQL Fiddle

MS SQL Server 2008的架構設置

Create Table dbo.Events (
    ID int not null primary key nonclustered, 
    EventDate datetime not null 
); 


Insert Into dbo.Events (ID, EventDate) Values 
    (1, '2011-11-19'), 
    (2, '2011-11-25'), 
    (3, '2011-12-12'), 
    (4, '2012-01-02'), 
    (5, '2012-01-05'), 
    (6, '2012-02-10'); 

查詢1

DECLARE @dtStart DATETIME, 
     @dtEnd DATETIME 

SET @dtStart = '2011-11-01' 
SET @dtEnd = '2012-02-20' 

SELECT thedate, 
     eventID = (SELECT TOP 1 id 
        FROM events 
        WHERE eventdate <= thedate 
        ORDER BY eventdate DESC) 
FROM (SELECT Dateadd(DAY, number, @dtStart) AS theDate --build dates from the start to end date 
     FROM (SELECT DISTINCT number 
       FROM master.dbo.spt_values 
       WHERE name IS NULL) n --returns integer values from 0 to 2037 
     WHERE Dateadd(DAY, number, @dtStart) < @dtEnd) x 

Results

|       THEDATE | EVENTID | 
--------------------------------------------- 
| November, 01 2011 00:00:00+0000 | (null) | 
| November, 02 2011 00:00:00+0000 | (null) | 
| November, 03 2011 00:00:00+0000 | (null) | 
| November, 04 2011 00:00:00+0000 | (null) | 
| November, 05 2011 00:00:00+0000 | (null) | 
| November, 06 2011 00:00:00+0000 | (null) | 
| November, 07 2011 00:00:00+0000 | (null) | 
| November, 08 2011 00:00:00+0000 | (null) | 
| November, 09 2011 00:00:00+0000 | (null) | 
| November, 10 2011 00:00:00+0000 | (null) | 
| November, 11 2011 00:00:00+0000 | (null) | 
| November, 12 2011 00:00:00+0000 | (null) | 
| November, 13 2011 00:00:00+0000 | (null) | 
| November, 14 2011 00:00:00+0000 | (null) | 
| November, 15 2011 00:00:00+0000 | (null) | 
| November, 16 2011 00:00:00+0000 | (null) | 
| November, 17 2011 00:00:00+0000 | (null) | 
| November, 18 2011 00:00:00+0000 | (null) | 
| November, 19 2011 00:00:00+0000 |  1 | 
| November, 20 2011 00:00:00+0000 |  1 | 
| November, 21 2011 00:00:00+0000 |  1 | 
| November, 22 2011 00:00:00+0000 |  1 | 
| November, 23 2011 00:00:00+0000 |  1 | 
| November, 24 2011 00:00:00+0000 |  1 | 
| November, 25 2011 00:00:00+0000 |  2 | 
| November, 26 2011 00:00:00+0000 |  2 | 
| November, 27 2011 00:00:00+0000 |  2 | 
| November, 28 2011 00:00:00+0000 |  2 | 
| November, 29 2011 00:00:00+0000 |  2 | 
| November, 30 2011 00:00:00+0000 |  2 | 
| December, 01 2011 00:00:00+0000 |  2 | 
| December, 02 2011 00:00:00+0000 |  2 | 
| December, 03 2011 00:00:00+0000 |  2 | 
| December, 04 2011 00:00:00+0000 |  2 | 
| December, 05 2011 00:00:00+0000 |  2 | 
| December, 06 2011 00:00:00+0000 |  2 | 
| December, 07 2011 00:00:00+0000 |  2 | 
| December, 08 2011 00:00:00+0000 |  2 | 
| December, 09 2011 00:00:00+0000 |  2 | 
| December, 10 2011 00:00:00+0000 |  2 | 
| December, 11 2011 00:00:00+0000 |  2 | 
| December, 12 2011 00:00:00+0000 |  3 | 
| December, 13 2011 00:00:00+0000 |  3 | 
| December, 14 2011 00:00:00+0000 |  3 | 
| December, 15 2011 00:00:00+0000 |  3 | 
| December, 16 2011 00:00:00+0000 |  3 | 
| December, 17 2011 00:00:00+0000 |  3 | 
| December, 18 2011 00:00:00+0000 |  3 | 
| December, 19 2011 00:00:00+0000 |  3 | 
| December, 20 2011 00:00:00+0000 |  3 | 
| December, 21 2011 00:00:00+0000 |  3 | 
| December, 22 2011 00:00:00+0000 |  3 | 
| December, 23 2011 00:00:00+0000 |  3 | 
| December, 24 2011 00:00:00+0000 |  3 | 
| December, 25 2011 00:00:00+0000 |  3 | 
| December, 26 2011 00:00:00+0000 |  3 | 
| December, 27 2011 00:00:00+0000 |  3 | 
| December, 28 2011 00:00:00+0000 |  3 | 
| December, 29 2011 00:00:00+0000 |  3 | 
| December, 30 2011 00:00:00+0000 |  3 | 
| December, 31 2011 00:00:00+0000 |  3 | 
| January, 01 2012 00:00:00+0000 |  3 | 
| January, 02 2012 00:00:00+0000 |  4 | 
| January, 03 2012 00:00:00+0000 |  4 | 
| January, 04 2012 00:00:00+0000 |  4 | 
| January, 05 2012 00:00:00+0000 |  5 | 
| January, 06 2012 00:00:00+0000 |  5 | 
| January, 07 2012 00:00:00+0000 |  5 | 
| January, 08 2012 00:00:00+0000 |  5 | 
| January, 09 2012 00:00:00+0000 |  5 | 
| January, 10 2012 00:00:00+0000 |  5 | 
| January, 11 2012 00:00:00+0000 |  5 | 
| January, 12 2012 00:00:00+0000 |  5 | 
| January, 13 2012 00:00:00+0000 |  5 | 
| January, 14 2012 00:00:00+0000 |  5 | 
| January, 15 2012 00:00:00+0000 |  5 | 
| January, 16 2012 00:00:00+0000 |  5 | 
| January, 17 2012 00:00:00+0000 |  5 | 
| January, 18 2012 00:00:00+0000 |  5 | 
| January, 19 2012 00:00:00+0000 |  5 | 
| January, 20 2012 00:00:00+0000 |  5 | 
| January, 21 2012 00:00:00+0000 |  5 | 
| January, 22 2012 00:00:00+0000 |  5 | 
| January, 23 2012 00:00:00+0000 |  5 | 
| January, 24 2012 00:00:00+0000 |  5 | 
| January, 25 2012 00:00:00+0000 |  5 | 
| January, 26 2012 00:00:00+0000 |  5 | 
| January, 27 2012 00:00:00+0000 |  5 | 
| January, 28 2012 00:00:00+0000 |  5 | 
| January, 29 2012 00:00:00+0000 |  5 | 
| January, 30 2012 00:00:00+0000 |  5 | 
| January, 31 2012 00:00:00+0000 |  5 | 
| February, 01 2012 00:00:00+0000 |  5 | 
| February, 02 2012 00:00:00+0000 |  5 | 
| February, 03 2012 00:00:00+0000 |  5 | 
| February, 04 2012 00:00:00+0000 |  5 | 
| February, 05 2012 00:00:00+0000 |  5 | 
| February, 06 2012 00:00:00+0000 |  5 | 
| February, 07 2012 00:00:00+0000 |  5 | 
| February, 08 2012 00:00:00+0000 |  5 | 
| February, 09 2012 00:00:00+0000 |  5 | 
| February, 10 2012 00:00:00+0000 |  6 | 
| February, 11 2012 00:00:00+0000 |  6 | 
| February, 12 2012 00:00:00+0000 |  6 | 
| February, 13 2012 00:00:00+0000 |  6 | 
| February, 14 2012 00:00:00+0000 |  6 | 
| February, 15 2012 00:00:00+0000 |  6 | 
| February, 16 2012 00:00:00+0000 |  6 | 
| February, 17 2012 00:00:00+0000 |  6 | 
| February, 18 2012 00:00:00+0000 |  6 | 
| February, 19 2012 00:00:00+0000 |  6 | 
2
select distinct 
e1.eventDate, 
ID = (
     select top 1 e2.ID 
     from Events e2 
     where e2.eventDate <= e1.eventDate 
     order by e2.eventDate desc 
    ) 
from 
Events e1 

當你從查詢中得到結果時,你會讓它們在代碼中循環並顯示結果。讓您的實現更高效的關鍵是減少數據庫往返次數。

1

您可以使用類似的查詢像下面,這樣你就可以一次檢索的事件ID,日期開始和日期結束的整個列表:

select id, date_start,(select min(date_start) from eventss where date_start > e.date_start) as date_end from 
eventss e where date_start >= @DateStart 
and 
(select min(date_start) from eventss 
where date_start > e.date_start) <= @DateEnd