0

私は、ユーザーが自分のワークステーションで各バッチに取り組んだ合計時間、完了した推定作業の合計、ユーザーに支払われた金額、ユーザーが今年 1 日で何回失敗したかを調べています。これらすべてを 1 つのクエリに結合できれば、それを Excel で使用して、ピボット テーブルなどで適切に書式設定できます。

編集:これは複数のクエリでのみ実行できることに気付いたので、スコープをこれに絞り込みました:

SELECT batch_log.userid,
batches.operation_id,
SUM(TIME_TO_SEC(ramses.batch_log.time_elapsed)),
SUM(ramses.tasks.estimated_nonrecurring + ramses.tasks.estimated_recurring),
DATE(start_time)
FROM batch_log
JOIN batches ON batch_log.batch_id=batches.id
JOIN ramses.tasks   ON ramses.batch_log.batch_id=ramses.tasks.batch_id
JOIN protocase.tblusers on ramses.batch_log.userid = protocase.tblusers.userid
WHERE DATE(ramses.batch_log.start_time) > "2011-01-01"
AND protocase.tblusers.active = 1
GROUP BY userid, batches.operation_id, start_time
ORDER BY start_time, userid ASC

クロス結合が問題の原因でした。

4

1 に答える 1

1

いいえ、一般的には、Having句を使用して結果をフィルタリングします。Group byたとえば、1 日に 24 時間以上支払われた人のみを報告します ( HAVING SUM(ramses.timesheet_detail.paidTime) > 24)。集計結果のフィルタリングを実行する必要がない限り、having句はまったく必要ありません。
これらの条件のほとんどはwhere、次の 2 つの理由から、句に移動するか、結合の一部として移動する必要があります。1) 一般に、クエリが実行する必要がある作業を制限するために、フィルタリングはできるだけ早く実行する必要があります。2) フィルタリングが既に行われている場合、それを言い換えると、クエリが追加の不要な作業を実行する可能性があります。
私がこれまで見てきたことから、あなたは日ごとに物事をまとめようとしているようです -group by句の最後の列を次のように変更してみてくださいdate(ramses.batch_log.start_time)、または(私が想定しているのは)タイムスタンプでグループ化しています。


編集:スキーマ名について - はい、セクションとセクション
で名前を付けることができます。多くの場合、クエリは、デフォルトの検索リストに基づいて必要なスキーマを解決できる場合があります (これを設定する方法または設定するかどうかは、データベースによって異なります)。 クエリを再フォーマットする方法は次のとおりです。 fromjoin

SELECT tblusers.userid, operations.name AS name,
SUM(TIME_TO_SEC(batch_log.time_elapsed)) AS time_elapsed,
SUM(tasks.estimated_nonrecurring + tasks.estimated_recurring) AS total_estimated,
SUM(timesheet_detail.paidTime) as hours_paid,
DATE(start_time) as date_paid
FROM tblusers
JOIN batch_log 
ON tblusers.userid = batch_log.userid 
AND DATE(batch_log.start_time) >= "2011-01-01" 
JOIN batches 
ON batch_log.batch_id = batches.id
JOIN operations 
ON operations.id = batches.operation_id
JOIN tasks
ON batches.id = tasks.batch_id
JOIN timesheet_detail 
ON tblusers.userid = timesheet_detail.userid 
AND batch_log.start_time = timesheet_detail.for_day
AND DATE(timesheet_detail.for_day) = DATE(start_time)
WHERE tblusers.departmentid = 8
GROUP BY tblusers.userid, name, DATE(batch_log.start_time)     
ORDER BY date_paid ASC 

特に懸念されるのは、batch_log.start_time = timesheet_detail.for_dayタイムスタンプ (であることを暗示するもの) を比較している行です。これらは本当に等しいのでしょうか?これらのいずれかまたは両方をdate()関数でラップする必要があると思います。

予期しないデータを取得する理由については、参加条件の一部を削除したようです。データベースの正確なセットアップと使用法を知らなければ、結果の正確な理由を示すことはできません (または、それらが間違っているとさえ言えます) operationsjoinそのテーブルに 2 つのレコードがある場合、以前の結果のすべてが 2 倍になり、12 のように見えます。またoperations.namegroup by句から削除したため、必要な結果が得られる場合とそうでない場合があります。残りのテーブルの関係を調べて、さらに制限を加える必要があるかどうかを確認します。

于 2011-06-29T17:09:30.273 に答える