2009-06-17 3 views
1

さまざまな日から、さまざまな範囲からいくつのインスタンスが発生するかを検討する必要があります。おそらく一例を挙げて説明するのが最も良いでしょう。上記の3つの例を使用して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(それゆえに^以上のフォーマット)、何百、何千ものレコードがあるので、あらゆる種類のループやif文を実行しようとする不毛な試みが永遠に続くでしょう。

これを行うには、かなり簡単で効率的な方法がありますか?私は本当にどこ残念ながら起動するにはあまりにもわからないんだけど...

おかげ

答えて

1

をしようとしています日付範囲をループする必要があります。

合計を行うには、いくつかの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に記載の方法を使用できます:あなたのDBエンジンまたはPHPコードのどちらか

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

多くのおかげでヴィンセント - 完璧に見える!しかし、1つの質問、とにかく自動的に日付を入力するにはありますか?それは何年も続くので、私はループして各日付などを表示する必要があります。:( ありがとうございました – Nick

+0

こんにちはニック、あなたは変数の値を入力して "カレンダー"サブクエリを入力します:begin_date "と":end_date " –

1

あなたが日ごとに1行を持つテーブルを必要とする

test_calendar:ここ

DFROM DTILL 
18.01.2009 21.01.2009 
19.01.2009 20.01.2009 
20.01.2009 20.01.2009 

はクエリです:

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と仕上がりが含まれています必要なもの:

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のいくつかと2番目の解決策のPHPのビットを使って解決してくれたソリューションの皆さんには大変感謝しています。

本当に感謝します:)