1

SaaS 用のカスタム レポート モジュールを作成していますが、作成中のクエリ (MySQL および PHP) について少しアドバイスが必要です。私は動的にテーブルを作成しています。返される各レコードは、そのテーブルの 1 つの行になります。多くの異なるテーブルを動的に結合し、結合する必要がある 3 つのテーブルを除いてすべてうまく機能します。

他のすべてのテーブルは 1 対 1 の LEFT JOIN です。たとえば、employee テーブルにクエリを実行して department_id を見つけようとすると、単にハンキー ドリーに結合されます。次のように結合します。

First | Last  | Dept
John  | Smith | Toy Department

これを複雑にしているのは、余分な 3 つのテーブルに 1 対多の結合があることです。この結合を行うと、2 行から 50 行のデータが引き出される可能性があることを指摘しておくことも重要です。たとえば、従業員テーブルにクエリを実行していて、出勤/退勤テーブルに参加する必要がある場合、次のようになります。

First | Last  | Time
John  | Smith | 8:00 am
John  | Smith | 12:00 pm
John  | Smith | 1:00 pm
John  | Smith | 5:00 pm

正しい結合を行った場合、姓/名は null になりますが、それでも複数の行があります。

それらを 1 行に保持したい理由は、レポートがプルされたときに設定しているテーブルで、3 つの 1-many テーブルのいずれかを使用する必要があるときに、それを保持する必要があるためです。同じデータ セル内 (これは私の制御範囲外であり、発生する必要があります):

<table>
    <tr>
        <td>John</td>
        <td>Smith</td>
        <td>8:00 am<br />12:00 pm<br />..... </td>
    </tr>
</table>

そのセルにヒットしてから、別のクエリを実行してすべてのデータを引き出す必要はありません。その理由は、25 列以上の数千行のレポートを実行し、同じクエリを 25x1000 の行で実行する可能性があるからです。

私が望んでいたのは、データが返されたときに次のようなものでした:

First | Last  | Time_1  | Time_2   | Time_3  | Time_4
John  | Smith | 8:00 am | 12:00 pm | 1:00 pm | 5:00 pm

私が持っていたいくつかの考えは、PHP で while ループを実行し、MySQL の結合を動的に構築することですが、その列を正しくするためにテーブルに結合する回数を指定する必要があるという事実の問題に遭遇します。 . 私は技術的に行うことができます:

for($i = 1; $i < 50; ++$i) {
    $sql_fields .= "time_clock_{$i}.time AS Time_{$i},";
    $joins .= "LEFT JOIN time_clock AS time_clock_{$i} ON time_clock_{$i}.employee_id = emp.id";
}
$sql_fields = rtrim($sql_fields,',');

mysql_query("SELECT emp.field_blah, emp.field_blah2, {$sql_fields} FROM employees AS emp {$joins} WHERE condition = blah");

これにより、MySQL とそこにあるすべてのクレイジーな結合でパフォーマンスの問題が実際に発生するのではないかと心配しています。誰でも良いアイデアがありますか?この時点で何でも楽しませてくれます。

4

2 に答える 2

1

いいえ。

2 つのクエリを作成します。すべての 1:1 要素を持つすべての人を引っ張るために 1 つ。次に、すべての時間をプルします。次に、PHP で時間をループし、それらを people の時間配列に詰め込みます。

于 2012-05-10T22:25:57.483 に答える
0
<?php
    $query = mysql_query("SELECT .... FROM employees LEFT JOIN.... LEFT JOIN..."); //even include the one-many tables
    $i = 0;
    while($rs = mysql_fetch_array($query)) { //note I'm using array not assoc
        // echo the 1:1 table data
        // when I hit the 1:many field do something like this, yes $j will get reset when the pointer hits the next row....I need more time to think....
        $j = 1;
        while($j) {
            if($rs[$i + $j]['id'] == $rs[$i]['id']) {
                echo $rs[$i + $j]['Time'];
                ++$skip_fields;
            } else {
                $j = 0;
            }
            ++$j;
        }
        // then use $skip_fields to skip $j number of rows that the duplicate employee ids are on and decrement the value as the pointer moves on.
        ++$i;
    }
?>

気にしないでください.....数値を使用すると、行ではなく列にのみヒットします.....まあ。:)

于 2012-05-10T22:47:53.840 に答える