重複を排除して各件数のカウント

タイトルの通り処理をしたく、色々と試したのでメモを残す。
結果的にはSQLでの処理はあきらめてプログラム側(PHP)で処理をした。

まず、やりたい内容について記載していく。

例えば、下記のようなテーブルがあるとする。
実際は複数のテーブルをjoinする内容なのだが簡単にしたいので一旦下記のように設定した。
テーブル名はshopとする。

prtsc1

ここでuserが田中で絞り込むと単純にこんな感じ。

SELECT * FROM shop WHERE user = '田中'

prtsc2

この結果に対して、
恵比寿 3
新宿 2
渋谷 1
という結果を求めたい。

まず重複した行をまとめるのにはDISTINCTを使う。

SELECT DISTINCT area FROM shop WHERE user = '田中'

prtsc3

それに対して件数のカウントをするのには下記のようにする。

SELECT DISTINCT area,count(*) FROM shop WHERE user = '田中' GROUP BY area

prtsc4

ここまでは問題なかったのであるが、実際に実行したい環境では複数のテーブルを複雑にJOINしていたため、結果の件数が結合したレコード分だけ大きくなってしまった。
イメージとしては下記のような感じ。

恵比寿 120
新宿 80
渋谷 40

上記の場合であれば単純に40で割ってしまえば期待する結果は取得できたのであるが、他のテーブルに変更があった場合に問題になる事が容易に想定できるので、他の手段を調べてみたがどうにも上手くできなかった。

そのような訳で結果的にはプログラム側(PHP)で処理をした。

参考にしたのは下記ページ

■array_count_values – 配列の値の数を数える
http://php.net/manual/ja/function.array-count-values.php

■配列のソート
http://php.net/manual/ja/array.sorting.php

<?php
$mysqli = new mysqli('localhost','root','password','db_name');
$mysqli->set_charset("utf8");
$sql = "SELECT * FROM shop WHERE user = '田中'";
$result = $mysqli->query($sql);
while ($row = $result->fetch_assoc()) {
    $result_arr[] = $row['area'];
}
$result_arr = array_count_values($result_arr);
arsort($result_arr);
foreach ($result_arr as $key => $value) {
  echo $key . ":" . $value . "件" . "<br>" ;
}

恵比寿:3件
新宿:2件
渋谷:1件

これで複雑にJOINしたケースでも期待する結果が表示できたのでOKとする。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です