6

作成日と閉鎖日を格納するテーブルがあります。私がやろうとしているのは、特定の期間に、毎日、作成されたレコードの数、閉じられたレコードの数、開いているレコードの数を取得するクエリを実行することです。テーブル構造:

+------------------------+
| Field      | Structure |
+------------+-----------+
| id         | int       |
| start_date | datetime  |
| close_date | datetime  |
+------------+-----------+

最初の 2 つのクエリは問題ではありません。現在取り組んでいるのは次のとおりです。

SELECT COUNT(*), start_date FROM dates 
WHERE start_date BETWEEN 'start' AND 'end' 
GROUP BY start_date 
ORDER BY start_date ASC

SELECT COUNT(*), close_date FROM dates 
WHERE close_date BETWEEN 'start' AND 'end' 
GROUP BY close_date 
ORDER BY close_date ASC

3 番目のクエリは問題です。その日がテーブルに存在する日に開いていた数を取得できますが、私が理解していないのは、毎日の行を年とその日のカウントを教えてください。

それが最初の問題です。

2つ目は、このような結果を得るためにそれを取得したいということです。その方法がわかりません.

+------------+--------+--------+--------+
|    Date    | Opened | Closed | Active |
+------------+--------+--------+--------+
| 2012-05-06 | 3      | 2      | 7      |
| 2012-05-07 | 2      | 0      | 9      |
| 2012-05-08 | 0      | 0      | 9      |
| 2012-05-09 | 0      | 3      | 6      |
+------------+--------+--------+--------+

必要に応じて個別のクエリを実行し、必要に応じて db ではなくコードですべてを処理することを完全にいとわない-個々のクエリからのすべてのクエリデータを単一の配列に書き込んでループすることができると確信しているそれを介してレポートを作成しますが、私はそうしないことを本当に望んでいます。助言がありますか?

4

3 に答える 3

0

このような集計テーブルを作成することは、SQLステートメントだけでは非常に困難です。サブクエリ、UNIONステートメント、および/または場合によってはストアドプロシージャを使用して、ロジックスポットを取得し、テーブルを提示するときにテーブルが表示されるようにする必要があります。

あなたがすでに持っている2つのクエリは、私が上で述べたアプローチよりもはるかに高速です。PHP配列は、必要なものを取得するのに間違いなく役立ちます。

それで:

ステップ1

SELECT COUNT(*) AS active_before_start 
WHERE start_date < 'start'
AND close_date IS NULL

その番号を取得し、$active_before_startに保存します。

ステップ2

SELECT COUNT(*) AS total_opened, start_date FROM dates 
WHERE start_date BETWEEN 'start' AND 'end' 
GROUP BY start_date 
ORDER BY start_date ASC

これらの結果を配列に入れます

foreach ($results as $result)
{
    $key = $result->start_date;
    $final_table[$key]['date']   = $key;
    $final_table[$key]['opened'] = $result->total_opened;
}

ステップ3

SELECT COUNT(*) AS total_closed, close_date FROM dates 
WHERE close_date BETWEEN 'start' AND 'end' 
GROUP BY close_date 
ORDER BY close_date ASC

再びそれらを配列に格納します

foreach ($results as $result)
{
    $key = $result->close_date;
    $final_table[$key]['date']   = $key;
    $final_table[$key]['closed'] = $result->total_closed;
}

ステップ4

これで、テーブルをトラバースしてデータを操作し、必要な結果を次のように生成できます。

$results_table = array();
$active        = $active_before_start;
foreach ($final_table as $key => $item)
{
    $opened = (isset($item['opened']) ? $item['opened'] : 0;
    $closed = (isset($item['closed']) ? $item['closed'] : 0;
    $active = $active + ($opened' - $closed);

    $results_table[$key]['date']   = $key;
    $results_table[$key]['opened'] = $opened;
    $results_table[$key]['closed'] = $closed;
    $results_table[$key]['active'] = $active;
}

それ以降は、ソートされた配列の結果を表示する場合に備えて、いつでもksortを実行できます。

HTH

于 2012-09-07T15:00:06.953 に答える
0

その日がテーブルに存在する日に開いていた数を教えてもらうことができますが、私が理解していないのは、その年の毎日の行を書き出させてカウントを与える方法ですその日のために。

私はそれを次のように理解しています: 締め切り日ごとに問題を数えたいですか?

SELECT COUNT(*) FROM dates WHERE your_condition GROUP BY DAY_OF_YEAR(close_date)
于 2012-09-07T14:12:00.550 に答える
0

範囲内のすべての日付のステータス リストが必要なため、このクエリは注意が必要です。

このクエリでは、結合クエリで日付が生成されます。そのために、同じテーブルがあると仮定して同じテーブルを使用しました

  • レコード数 >= daterange 間の日付の数
  • id-s は、daterange 間の日付の数まで連続している必要があります

これを独自の日付リスト生成サブクエリに置き換えることができます。

set @start :='2012-05-06';
set @end :='2012-05-09';

select cdate as Date
     , sum(start_date = cdate) Opened
     , sum(close_date = cdate or close_date is null) Closed
     , sum(start_date <= cdate and (close_date>cdate or close_date is null)) Active
from dates
join (select date(@start + interval id-1 day) cdate from dates where id <= to_days(@end)-to_days(@start)+1) d
  on start_date <= cdate and (close_date>=cdate or close_date is null)
where start_date <= @end 
  and (close_date >= @start or close_date is null)
group by cdate
order by cdate
;
于 2012-09-07T18:48:40.307 に答える