MySQLのデータをソートして表示しようぜ

PHP で MySQL のデータを引っ張ってくるところは　前回の記事で作ったのだった。

関連記事：http://qiita.com/muzudho1/items/deea9da28b0f5b0c3695

# 今回やりたいこと

テーブル名: TAMESI1

|NAME|AGE|WEIGHT|
|---|---|---|
|太郎|14|50|
|二郎|13|49|
|三郎|12|48|

といったテーブルを前回　用意したのだった。

- 年齢順
- 体重順

という２つのハイパーテキスト・リンクを用意し、並び替えて表示したい。

URLの末尾に ?s=age と付いていれば年齢順、s=weight と付いていれば体重順でいいのではないか？

ファースト・ビューで上位１０名まで表示し、１１位以降は　スクロールバーで隠すとする。

# PHP と SQL

前回は次のように書いた。

table1.php 抜粋

```php
// 完成済みのSELECT文を実行する
$sql = 'SELECT NAME, AGE, WEIGHT FROM TAMESI1';
if ($result = $mysqli->query($sql)) {
    // 連想配列を取得
    while ($row = $result->fetch_assoc()) {
        echo $row['NAME'] . ', ' . $row['AGE'] . ', ' . $row['WEIGHT'] . '<br />';
    }
    // 結果セットを閉じる
    $result->close();
}
```

コード全体は前回の記事参照。
関連記事：http://qiita.com/muzudho1/items/deea9da28b0f5b0c3695

「[PHP] mysqli使い方まとめ（MySQL接続～SELECT実行まで）」Qiita
http://qiita.com/yasumodev/items/bd2ba476f31804d527d3

これに、年齢の高い者順ソートを付けたい。

「ソート」さすけのプログラミング入門
http://sasuke.main.jp/order.html

次のように１行　改造した。

table2.php

```php
$sql = 'SELECT NAME, AGE, WEIGHT FROM TAMESI1 ORDER BY AGE DESC';
```

![Gazo](https://github.com/muzudho/HowToMakeGame/blob/master/img/2017-04/20170410a1.png?raw=true)

年齢順に並んでいそうだ。体重も同じリクツでできるだろう。

# GET文字列を使おうぜ

URLの末尾に ?s=age と付いていれば年齢順、s=weight と付いていれば体重順になるように　コードを改造したい。

table3.php 抜粋

```php
$query = 'SELECT NAME, AGE, WEIGHT FROM TAMESI1';

// URLの末尾に ?s=weight または ?s=age を付けていた場合（または付けていなかった場合）の処理分け
switch($_GET['s']){
    case "weight":
        $query .= ' ORDER BY WEIGHT DESC'; // ORDER BY は ? でバインドできないので埋め込んだ。
        break;
    case "age": // thru
    default:
        $query .= ' ORDER BY AGE DESC';
        break;
}

if ($result = $mysqli->query($query)) {
    // 連想配列を取得
    while ($row = $result->fetch_assoc()) {
        echo $row['NAME'] . ', ' . $row['AGE'] . ', ' . $row['WEIGHT'] . '<br />';
    }
    // 結果セットを閉じる
    $result->close();
}
```

「mysqlユーザーのためのmysqliラッパー」Qiita
http://qiita.com/taro_3000/items/f9db8f816cf3837b59b9

これでおっけ！

# データ値を一通り読み込み、そのデータ値を　絞り込み条件に使いたい

そんなん、マスターを用意しとけ、と思うんだが　設計費をもらえないところは杜撰にやる方針だ。　わけのわからん設計されたものより、杜撰にやった方が喜ばれるときがある。「想定されるデータの分量から問題ない」あるいは「手間をかけていない、指示通りコスト少なく早くできた」とでも思われているのか、「細かく言うとプログラマーが対応できない、わたしの指示の出し方が良かった」とでも思われているのかもしれない。

```php
$query = 'SELECT DISTINCT WEIGHT FROM TAMESI1 ORDER BY WEIGHT';

if ($result = $mysqli->query($query)) {
    // 連想配列を取得
    while ($row = $result->fetch_assoc()) {
        echo '<a href="./' . basename($_SERVER['PHP_SELF']) . '?c=' . $row['WEIGHT'] . '">' . $row['WEIGHT'] . '</a><br />'. "\n";
    }
    // 結果セットを閉じる
    $result->close();
}
```

![Gazo](https://github.com/muzudho/HowToMakeGame/blob/master/img/2017-04/20170410a2.png?raw=true)

十分。これを　GET文字列で送信して 絞り込み検索のキーに使いたい。

「SQL SELECT DISTINCT Statement」w3schools.com
https://www.w3schools.com/sql/sql_distinct.asp

「PHPで自分のファイル名を取得する方法」NeGiMeMo.net
http://negimemo.net/1705

# 絞り込み条件も渡そう

table5.php

```php
// ここにDB処理いろいろ書く

//----------
// 絞り込み検索値
//----------
$query = 'SELECT DISTINCT WEIGHT FROM TAMESI1 ORDER BY WEIGHT';
if ($result = $mysqli->query($query)) {
    // 連想配列を取得
    while ($row = $result->fetch_assoc()) {
        // URLの末尾に絞り込み条件「?c=体重」を付けます
        echo '<a href="./' . basename($_SERVER['PHP_SELF']) . '?c=' . $row['WEIGHT'] . '">' . $row['WEIGHT'] . '</a> '. "\n";
    }
    echo '<br />' . "\n";
    // 結果セットを閉じる
    $result->close();
}

//----------
// テーブル表示
//----------
$query = 'SELECT NAME, AGE, WEIGHT FROM TAMESI1 WHERE WEIGHT = ? ORDER BY AGE DESC';
$stmt = $mysqli->stmt_init();
if(!$stmt->prepare($query))
{
    print "Failed to prepare statement\n";
}
else
{
    // 条件値をSQLにバインドする
    // bind_param の第１引数 "is" は後続のデータ型を表します。
    // i=integer、s=string、d=double、b=blob など。DATE型は s で良いみたいです。
    // また下記のように値を引数内に直書きすることはできません。
    // 誤）$stmt->bind_param("is", 123, "hanako");
    
    // c...criteria 検索条件
    $c_weight = $_GET['c'];
    if(is_numeric($c_weight)){
        $stmt->bind_param('i', $c_weight);

        // 実行
        $stmt->execute();

        // 結果はこの変数に入れるようにする
        $stmt->bind_result($name, $age, $weight);
        while ($stmt->fetch()) {
            echo $name . ', ' . $age . ', ' . $weight . '<br />';
        }
    }
    else
    {
        echo '?c=(weight number) not found.';
    }

    // 結果セットを閉じる
    $stmt->close();
}
```

![Gazo](https://github.com/muzudho/HowToMakeGame/blob/master/img/2017-04/20170410a3.png?raw=true)

データが化けているが　47 で絞り込むというのはできているぜ。上出来。

# ファースト・ビューでデータの上位10件だけ表示して、11位以降はスクロールバーで見れるようにする

そんなことはやりたくない、と言うと代案を出さなくてはいけなくなり　めんどくさい　ので、やりたくないことをやることにする方針だぜ。

iframeなんか率先して使いたいものでもないし、CSS でググるか……。

「スクロールバー付きのボックスを設定する」eWeb
http://css.eweb-design.com/0807_sb.html

「＜テーブル＞　　*　 テーブル・セルにスクロールバーをつける　*」ホームページの小技あれこれ
http://kowaza.boo.jp/03table/table-07-0scroll.html

table6.php 抜粋

```php
// ここにDB処理いろいろ書く

//----------
// 絞り込み検索値
//----------
$query = 'SELECT DISTINCT WEIGHT FROM TAMESI1 ORDER BY WEIGHT';
if ($result = $mysqli->query($query)) {
    // 連想配列を取得
    while ($row = $result->fetch_assoc()) {
        // URLの末尾に絞り込み条件「?c=体重」を付けます
        echo '<a href="./' . basename($_SERVER['PHP_SELF']) . '?c=' . $row['WEIGHT'] . '">' . $row['WEIGHT'] . '</a> '. "\n";
    }
    echo '<br />' . "\n";
    // 結果セットを閉じる
    $result->close();
}

//----------
// テーブル表示
//----------
$query = 'SELECT NAME, AGE, WEIGHT FROM TAMESI1 WHERE WEIGHT = ? ORDER BY AGE DESC';
$stmt = $mysqli->stmt_init();
if(!$stmt->prepare($query))
{
    print "Failed to prepare statement\n";
}
else
{
    // 条件値をSQLにバインドする
    // bind_param の第１引数 "is" は後続のデータ型を表します。
    // i=integer、s=string、d=double、b=blob など。DATE型は s で良いみたいです。
    // また下記のように値を引数内に直書きすることはできません。
    // 誤）$stmt->bind_param("is", 123, "hanako");
    
    // c...criteria 検索条件
    $c_weight = $_GET['c'];
    if(is_numeric($c_weight)){
        $stmt->bind_param('i', $c_weight);

        // 実行
        $stmt->execute();

        // 結果はこの変数に入れるようにする
        $stmt->bind_result($name, $age, $weight);

?>
<div style="height:90px; width:300px; overflow-y:scroll;">
<table>
<?php
        while ($stmt->fetch()) {
            echo '<tr><td>' . $name . '</td><td>' . $age . '</td><td>' . $weight . '</td></tr>' . "\n";
        }
?>
</table>
</div>
<?php
    }
    else
    {
        echo 'error: weight not found.';
    }

    // 結果セットを閉じる
    $stmt->close();
}
```

![Gazo](https://github.com/muzudho/HowToMakeGame/blob/master/img/2017-04/20170410a4.png?raw=true)

これで十分じゃないか。

でけた！