【问题标题】:Working with date ranges in PHP/Oracle在 PHP/Oracle 中使用日期范围
【发布时间】:2010-11-03 14:32:43
【问题描述】:

我需要计算出在不同的一天发生了多少个不同的实例,来自许多不同的范围。可能最好用一个例子来解释它。

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 中获取信息(因此是上面的格式 ^),并且会有数百甚至数千条记录,所以我蹩脚的尝试做各种循环和 if 语句会永远运行。

是否有任何相当简单有效的方法来做到这一点?不幸的是,我真的不太确定从哪里开始......

谢谢

【问题讨论】:

    标签: php oracle date range


    【解决方案1】:

    您可以使用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
    

    【讨论】:

    • 非常感谢文森特 - 看起来很完美!但是有一个问题,是否有自动填充日期?它会跨越数年,所以我几乎需要它来循环显示每个日期,或者其他东西...... :( 谢谢
    • 嗨尼克,您可以通过输入变量“:begin_date”和“:end_date”的值来填充“日历”子查询
    【解决方案2】:

    您的数据库引擎或您的 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>";
      }
    }
    
    ?>
    

    【讨论】:

      【解决方案3】:

      你需要一张每天一排的表格

      测试日历:

      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
      

      table test包含bagin和finish of inctance:

      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
      

      【讨论】:

        【解决方案4】:

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

        真的很感激,干杯:)

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-10-25
          • 2012-02-19
          • 1970-01-01
          • 2014-06-09
          • 1970-01-01
          • 1970-01-01
          • 2014-05-20
          • 2010-10-12
          相关资源
          最近更新 更多