Работа с диапазонами дат в PHP / Oracle

1

Мне нужно выяснить, сколько разных экземпляров происходит в другой день из разных диапазонов. Наверное, лучше всего объяснить это на примере.

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 (следовательно, формат выше ^), и будут сотни, а может быть тысячи записей, поэтому мои хромые пытаются делать всевозможные циклы, и если бы инструкции навсегда бежать.

Есть ли достаточно простой и эффективный способ сделать это? Я действительно не слишком уверен, с чего начать, к сожалению...

Спасибо

Теги:
date
range

4 ответа

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

Вы можете использовать метод, описанный в другое 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
    Большое спасибо Винсент - это выглядит отлично! Один вопрос, хотя, есть ли возможность автоматически заполнять дату? Это будет длиться годами, поэтому мне нужно, чтобы оно почти перебирало и отображало каждую дату или что-то в этом роде ... :( Спасибо
  • 0
    Привет, Ник, вы бы заполнили подзапрос "calendar", введя значения для переменных ": begin_date" и ": end_date"
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

table test содержит бахин и финишную обработку:

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 из второго решения.

Действительно оценивайте это, приветствуйте:)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню