2009-06-17 83 views
1

我需要计算出多个不同实例在多个不同范围内发生的情况。可能最好用一个例子来解释它。在PHP/Oracle中使用日期范围

18-JAN-09 to 21-JAN-09 
19-JAN09 to 20-JAN-09 
20-JAN-09 to 20-JAN-09 

使用上面的三个例子,我需要它来收集这些信息,并显示的东西有点像...

18th Jan: 1 
19th Jan: 2 
20th Jan: 3 
21st Jan: 1 

...我会从Oracle数据库中抓取信息fwiw(因此上面的格式为^),并且将会有成百上千个记录,所以我的跛脚试图做各种循环,并且如果语句会永远运行。

有没有相当简单而有效的方法呢?我真的不太知道从哪里开始很遗憾...

感谢

回答

1

无论你的数据库引擎或你的PHP代码将必须在日期范围内循环。

下面是一些PHP代码来进行求和。日计数存储在year-month,以避免在广泛的日期范围内有一个巨大的阵列。

<?php 

// Get the date ranges from the database, hardcoded for example 
$dateRanges[0][0] = mktime(0, 0, 0, 1, 18, 2009); 
$dateRanges[0][1] = mktime(0, 0, 0, 1, 21, 2009); 
$dateRanges[1][0] = mktime(0, 0, 0, 1, 19, 2009); 
$dateRanges[1][1] = mktime(0, 0, 0, 1, 20, 2009); 
$dateRanges[2][0] = mktime(0, 0, 0, 1, 20, 2009); 
$dateRanges[2][1] = mktime(0, 0, 0, 1, 20, 2009); 

for ($rangeIndex = 0; $rangeIndex < sizeof($dateRanges); $rangeIndex++) 
{ 
    $startDate = $dateRanges[$rangeIndex][0]; 
    $endDate = $dateRanges[$rangeIndex][1]; 

    // Add 60 x 60 x 24 = 86400 seconds for each day 
    for ($thisDate = $startDate; $thisDate <= $endDate; $thisDate += 86400) 
    { 
    $yearMonth = date("Y-m", $thisDate); 
    $day = date("d", $thisDate); 

    // Store the count by year-month, then by day 
    $months[$yearMonth][$day]++; 
    } 
} 

foreach ($months as $yearMonth => $dayCounts) 
{ 
    foreach ($dayCounts as $dayNumber => $dayCount) 
    { 
    echo $yearMonth . "-" . $dayNumber . ": " . $dayCount . "<br>"; 
    } 
} 

?> 
2

你可以使用another SO介绍的方法:

SQL> WITH DATA AS (
    2 SELECT to_date('18-JAN-09', 'dd-mon-rr') begin_date, 
    3   to_date('21-JAN-09', 'dd-mon-rr') end_date FROM dual UNION ALL 
    4 SELECT to_date('19-JAN-09', 'dd-mon-rr'), 
    5   to_date('20-JAN-09', 'dd-mon-rr') FROM dual UNION ALL 
    6 SELECT to_date('20-JAN-09', 'dd-mon-rr'), 
    7   to_date('20-JAN-09', 'dd-mon-rr') FROM dual 
    8 ),calendar AS (
    9 SELECT to_date(:begin_date, 'dd-mon-rr') + ROWNUM - 1 c_date 
10 FROM dual 
11 CONNECT BY LEVEL <= to_date(:end_date, 'dd-mon-rr') 
12      - to_date(:begin_date, 'dd-mon-rr') + 1 
13 ) 
14 SELECT c.c_date, COUNT(d.begin_date) 
15 FROM calendar c 
16 LEFT JOIN DATA d ON c.c_date BETWEEN d.begin_date AND d.end_date 
17 GROUP BY c.c_date 
18 ORDER BY c.c_date; 

C_DATE  COUNT(D.BEGIN_DATE) 
----------- ------------------- 
18/01/2009     1 
19/01/2009     2 
20/01/2009     3 
21/01/2009     1 
+0

非常感谢文森特 - 看起来很完美!但有一个问题,是否有自动填充日期?它会跨越多年,所以我需要它几乎循环显示每个日期,或什么... :( 谢谢 – Nick 2009-06-17 09:40:47

1

你需要一个表一行每天

test_calendar:

Day 
16.01.2009 
17.01.2009 
18.01.2009 
19.01.2009 
20.01.2009 
21.01.2009 
22.01.2009 
23.01.2009 
24.01.2009 
25.01.2009 
26.01.2009 

台试验包含inctance的bagin和完成:

DFROM DTILL 
18.01.2009 21.01.2009 
19.01.2009 20.01.2009 
20.01.2009 20.01.2009 

下面是一个查询你需要:

select day, (select count(1) 
    from test where dfrom<=t.day and dtill>=t.day) from test_calendar t 
where day>to_date('15.01.2009','DD.MM.YYYY') 
order by day 
0

非常感谢解决方案人员 - 设法使用上面的一些SQL和第二个解决方案中的一些PHP工作。

真的很感激它,欢呼:)