4

この DB にクエリを実行して各行を取得する必要がありますが、結果の列値の 1 つの SUM も取得する必要があります。php を使用して合計値を取得することもできますが、合計を取得するために 2 つのループを実行する必要があります (結果の上部に表示されます)。したがって、クエリでそれをキャッチして「合計」行を作成することをお勧めしますが、それを機能させる唯一の方法は、本質的に元のクエリの繰り返しであるサブクエリを使用することです。より良い方法はありますか?

SELECT 
CONCAT(u.firstname, ' ', u.lastname ) name, u.id, s.description, s.shiftstart, s.shiftend, 
    (SELECT 
    SUM( TIME_TO_SEC( TIMEDIFF( shiftend, shiftstart ) ) ) /3600
    FROM shifts
    WHERE id =  '$user'
    AND DATE( shiftstart )
    BETWEEN '$start'
    AND '$end') total
FROM shifts s
INNER JOIN users u ON ( s.id = u.id )
WHERE s.id = '$user'
AND DATE( shiftstart )
BETWEEN '$start'
AND '$end'
ORDER BY shiftstart

上記は機能し、次のように出力されます。

name        id     description  shiftstart             shiftend               total
Joe User    joeuser    Stuff    2009-01-05 07:45:00    2009-01-05 12:15:00    39.5000
Joe User    joeuser    Stuff    2009-01-05 13:00:00    2009-01-05 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 07:45:00    2009-01-06 10:45:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 10:45:00    2009-01-06 12:45:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 13:30:00    2009-01-06 14:30:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 14:30:00    2009-01-06 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-07 09:45:00    2009-01-07 14:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-07 15:00:00    2009-01-07 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-08 08:00:00    2009-01-08 12:15:00    39.5000
Joe User    joeuser    Stuff    2009-01-08 13:15:00    2009-01-08 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-09 07:45:00    2009-01-09 10:45:00    39.5000
Joe User    joeuser    Stuff    2009-01-09 11:45:00    2009-01-09 15:15:00    39.5000
Joe User    joeuser    Stuff    2009-01-09 15:15:00    2009-01-09 17:00:00    39.5000

これは私が必要とするものですが、おそらくそれを取得する最良の方法ではありません.

4

4 に答える 4

3

より良い方法は、コードでこれを行うことです。手続き上の義務を果たすために、リレーショナル代数である SQL を使用することを主張し続けています。プロシージャル性を SQL に押し付けようとするのは、複雑さとパフォーマンスの両方の点で常に悪い考えです。プロの DBA からのアドバイスを参考にしてください。

コードから 2 つのクエリを実行します。最初に大きなセットを出力してから、必要な形式で合計行を出力します。クエリはより小さくシンプルになり、パフォーマンスが向上し、必要な出力が得られます。

その他のアドバイス - ディスク容量は安価であり、ほとんどのデータベース テーブルは書き込まれるよりもはるかに頻繁に読み取られます。挿入/更新トリガーを設定して (MySQL で可能であれば)、別の列に " CONCAT(u.firstname,' ',u.lastname)" などの計算フィールドを入力し、それをクエリに使用します。行ごとの関数はスケーラブルではなく、大きくなると DBMS のパフォーマンスが低下します。

于 2009-01-28T23:50:44.973 に答える
0

比較すると、何でも良くなる可能性があります。問題は何との比較ですよね?

あなたが指摘した重要な問題は、結果の上部に合計を表示したかったということです。Crystal Reports やその他のアプリは、2 パス エンジンであることによって、この種の魔法を管理します。最初のパスは合計を取得します。

どのソリューションにもトレードオフがあります。別の「合計」行を取得した場合、受信アプリは結果からそれを取り除くか、それを非表示にするために他のトリックを実行する必要があります。

1 時間あたり 100 万ヒットの Web サイト向けに書いていない場合のオプションとなる 1 つの可能性は、単純に 2 つの呼び出しを行うことです。詳細 ... 1 人の結果を選択しているクエリから表示されます。

私たちは皆、オーバーヘッドと帯域幅を節約することを望んでいますが、シンプルな方が良い場合もあります...

編集:パックスは私を「保存」ボタンに打ち負かしました...笑...

于 2009-01-28T23:52:33.940 に答える