2

MySQL データベースの特定の情報に基づいて HTML テーブルを作成しています。データベースから必要なテーブルには、行 ( rowidrowname )、列 ( columnidcolumnname ) およびセル データのデータが保持されます。行と列の ID をリンクするテーブル ( cellidrowidcolumnidsomedata )。テーブルは次のようになります。

__________| column1  | column2  | column3  | ...
     row1 | somedata | somedata |          |
----------|----------|----------|----------|-----
     row2 | somedata |          | somedata |
----------|----------|----------|----------|-----
...       |          |          |          |

私のアプローチは、次のようなネストされた foreach ループをいくつか使用することでした。

$rows = new Rows();        //These objects are containers for objects
$columns = new Columns();  //that hold some of the database data. 
$alldata = new Alldata();  //MySQL queries within these objects are irrelevant, I think. They already get the relevant data

$count = count($alldata);

echo "<table>";
echo "<tr>";
echo "<td>&nbsp;</td>";

foreach ($columns->getColumns() as $column) {
    echo "<td>".$column->getColumnname()."</td>";
}

echo "</tr>";

foreach ($rows->getRows() as $row) {
    echo "<tr>";
    echo "<td>".$row->getRowname()."</td>";

    foreach ($columns->getColumns() as $column) {
        $last = 1;

        foreach ($alldata->getAlldata() as $data) {
            if ($data->getCID() == $column->getID() & $data->getRID() == $row->getID()) { //If the column has data the related to the row
                echo "<td>".$data->getSomedata()."</td>";
                break;
            }
            if ($last == $count) { //if loop couldn't find any entries, it prints an empty cell
                echo "<td>&nbsp;<td>";
            }
            $last++
        }
    }
    echo "</tr>";
}
echo "</table>";

ブルートフォース、明らかに、データベース内のテーブルに数百行のデータがある場合、これはあまり効率的な方法ではなく、私はこれが好きではありません。これをより効率的にする方法はありますか?必要なテーブルを作成するより良い方法はありますか?

編集:
この問題について 1 週間熟考した結果、最終的にいくつかの答えが得られました。とてもシンプルでした!Columnオブジェクト クラス
に若干の変更を加えました。以前、私のコードは、データベース内のcelldataテーブルで可能なすべてのエントリを調べていました。これで、 Columnオブジェクトは、columnidが一致するcelldata の配列を取得し、そのデータのみを使用して比較を行うことができます。

$rows = new Rows();
$columns = new Columns();

echo "<table>";
echo "<tr>";
echo "<td>&nbsp;</td>";

foreach ($columns->getColumns() as $column) {
    echo "<td>".$column->getColumnname()."</td>";
}

echo "</tr>";

foreach ($rows->getRows() as $row) {
    echo "<tr>";
    echo "<td>".$row->getRowname()."</td>";

    foreach ($columns->getColumns() as $column) {
        $last = 1;
        $count = count($column->getAlldata());

        foreach ($column->getAlldata() as $data) {
            if ($data->getCID() == $column->getID() & $data->getRID() == $row->getID()) {
                echo "<td>".$data->getSomedata()."</td>";
                break;
            }
            if ($last == $count) {
                echo "<td>&nbsp;<td>";
            }
            $last++
        }
    }
    echo "</tr>";
}
echo "</table>";

はるかに高速ですが、まだブルートフォースですが、通過するデータ量は少なくなります。もちろん、ここでの問題は、列の数によっては、オブジェクトが非常に多くの MySQL クエリを実行する可能性があることです。

4

2 に答える 2

1

$alldataテーブルを結合ORDER BYし、クエリで句を指定することにより、MySQL からフェッチされたデータが正しく順序付けられていることを確認する場合:

SELECT   data.*
FROM     data RIGHT JOIN rows USING (rowid) RIGHT JOIN columns USING (columnid)
ORDER BY rowname, columnname;

次に、各セルを順番に出力するだけです。

echo '<table>';

echo '<thead>'
echo '<tr>';
echo '<th>&nbsp;</th>';
foreach ($columns->getColumns() as $column) {
    echo '<th scope="col">', htmlentities($column->getColumnname()), '</th>';
}
echo '</tr>';
echo '</thead>';

echo '<tbody>';
$data = $alldata->getAlldata();
foreach ($rows->getRows() as $row) {
    echo '<tr>';

    echo '<th scope="row">', htmlentities($row->getRowname()), '</th>';
    foreach ($columns->getColumns() as $column) {
        $d = each($data);
        echo '<td>', ($d ? htmlentities($d[1]->getSomedata()) : '&nbsp;'), '</td>';
    }

    echo '</tr>';
}
echo '</tbody>';

echo '</table>';
于 2012-06-30T07:42:36.180 に答える
0

これを解決する最善の方法$alldataは、eggyal が提案したように、クエリを書き直して、必要な順序になるようにすることです。なんらかの理由でそれができない場合は$alldata、最初から反復して、そこから適切にインデックス付けされた配列を作成できます。このようなもの:

$ordereddata = array();
foreach($alldata as $d) {
    $ordereddata[$d->getCID()][$d->getRID()] = $d->getSomedata();
}

foreach($alldata)これで、ループを次のように置き換えることができます。

if(isset($ordereddata[$column->getID()][$row->getID()])) {
    echo "<td>{$ordereddata[$column->getID()][$row->getID()]}</td>";
} else {
    echo "<td>&nbsp;</td>";
}
于 2012-06-30T08:26:46.467 に答える