PHP Manual
/
データ処理

PHPでのコンティンジェンシーテーブル

13. 11. 2019

分割表は、一般的に2つの統計現象の関係を示すために使用される。Webアプリケーションを開発する際、データベース内のある現象と、管理画面を代表とする時系列との関係を可視化する必要が生じることがよくあります。

例えば、個別の製品を示す受注表があり、ある大量生産された製品の売上が時間とどのように関連しているかに興味があります。

その際、以下のような表があると便利です。

デーツ|りんご|いちご|洋ナシ|など。
2019-05
2019-04
2019-03
2019-02
2019-01

PHPでこのフォームにデータを準備する簡単な方法はありませんし、SQLで直接このフォームにデータを取得するのも、カラムの数が動的であることを考慮しなければならないため、エレガントとは言えません。

そのため、このデータ構造の出力を設計する際には、頭を使う必要がある。

キーによるデータのシリアライズ

テーブルを作るとき、間隔データなど、与えられた条件を満たすすべてのレコードをデータベースから直接取得することをよく使う。

具体的には

SELECT *
FROM `order`
WHERE `inserted_date` <= '2019-05-01'
ORDER BY `inserted_date` DESC

このクエリは、order テーブル (order) のすべてのカラムを取得し、年代の初めから 2019-05-01 までのすべてのレコードをフィルタリングし、新しいものから古いものへとソートして返します。

簡単なSQLクエリで、ほぼ瞬時にデータを取得することができるのです。2つ目の良い点は、結果をまとめる際にデータベースのインデックスを効率的に利用できることです。しかし、データはプレーンな配列で持っているので、さらに手作業でコンティグテーブルに変換できるデータ構造にシリアライズする必要があります。

分割表は2つ以上の要因の関係を記述するため、多次元キーを使用することは理にかなっている。ただし、すべての組み合わせに対してデータが存在しない場合もあるので、キーを1つの文字列にシリアライズして、フラットな配列としてデータを格納するのがよい。

データは1回のループパスで組み立てることができる(変数 $selection にはデータベースからの出力が格納される)。

$data = [];
foreach ($selection as $row) {
$date = date('ワイエム', $row->insertedDate); // 日付 年月日
foreach ($row->items as $product) { // 製品を調べてみる
$key = $date . '_' . $product->id;
if (isset($data[$key])) {
$data[$key]++; // が存在する場合は、別の製品を追加します。
} else {
$data[$key] = 1; // が存在しない場合、最初の製品を開始します。
}
}
}

もし、もっとシンプルなデータ構造を検討していたなら、商品をブラウズするためのインナーループは必要ないでしょう。この場合、データ構築のすべてを1サイクルで解決することができる。

この方法では、2次元の情報を格納しながら、`key: value' のような、いわゆるフラットな配列が得られます。

すると、例えば(2019年5月に、IDが10の商品が6個売れた)と出力されます。

$data = [
'2019-05_10' => 6,
...
];

データをテーブルにレンダリングする - テンプレート

データをフラットな配列で持っていれば、テーブル全体を非常に簡単にレンダリングすることができる。そのためには、対象となるすべての商品のフィールドと、表をプロットしたいすべての日付のフィールドを知るだけでよい。

$products = [ ... ]; // プロダクトフィールド: id => name
$dates = [ ... ]; // 日付別:日付 => ラベル
echo '<table>';
foreach ($products as $productId => $productName) {
echo '<tr>';
foreach ($dates as $date => $dateLabel) {
echo '<td>';
echo htmlspecialchars(
(string) ($data[$date . '_' . $productId] ?? '0')
);
echo '<td>';
}
echo '</tr';
}
echo '</table>。';

なお、データを閲覧する際には、文字列キーの折りたたみによって特定の出現箇所を探す。この手法により、閲覧するデータに応じてレンダリングテーブルを任意に制約したり拡張したりすることができる。データが存在しない場合は,三項演算子 ? が評価され,0が表示される.

データを準備する最初のサイクルの一部として、利用可能な商品と日付の配列を構築することができます。その時点で、実際に存在するデータのみをプロットしていることを確認することができます。この場合、SQLデータベースからの出力が作成日でソートされていることが非常に重要で、そうでないと、最終的なテーブルレンダリング時に行がシャッフルされる可能性があります。

Jan Barášek   Více o autorovi

Autor článku pracuje jako seniorní vývojář a software architekt v Praze. Navrhuje a spravuje velké webové aplikace, které znáte a používáte. Od roku 2009 nabral bohaté zkušenosti, které tímto webem předává dál.

Rád vám pomůžu:

Související články

1.
3.
Status:
All systems normal.
2024