2

worktodo と workdone の 2 つのテーブルを持つ MS SqlServer 2008 データベースがあります。

CREATE TABLE worktodo
(
    workorder VARCHAR(32),
    worker VARCHAR(64),
    duedate DATETIME,
    PRIMARY KEY workorder
);
CREATE TABLE workdone
(
    workorder VARCHAR(32),
    donedate DATETIME
);

そして、ワーカーごとに、worktodos の総数と遅延した worktodos の総数を返すクエリを探しています。ここで、late は donedate > duedate、または duedate > NOW として定義され、workdone レコードはありません。

コードで行うのは簡単ですが、単純なレポート ツールで実行できるクエリが必要です。

何か案は?

EDITED:サンプルデータを追加しました:

worktodo:
workorder  worker  duedate
10001      JOE     2012-01-01
10002      JOE     2012-01-02
10003      FRED    2012-01-03
10004      BILL    2013-12-31

workdone:
worker     donedate
10001      2011-01-01
10002      2011-12-30
10002      2012-01-04

Desired:
worker   num_total_workorders   num_late_workorders
BILL     1                      0
FRED     1                      1
JOE      2                      1

Bill には 1 つの worktodo があり、これには子 workdon はありません。しかし、期日が将来であるため、彼には 1 つの作業指示書があり、遅延した作業指示書はありません。

Fred には 1 つの worktodo がありますが、これには子 workdon はありません。しかし、期日が過ぎているため、彼には 1 つの作業指示書と 1 つの遅れた作業指示書があります。

Joe には 2 つの仕事の ToDo があります。Workorder 10001 の期日は 2012-01-01 でしたが、2012-01-31 まで完了していなかったため、遅れています。作業指示 10002 の期日は 2012 年 1 月 2 日でしたが、最も早い作業はそれ以前の 2011 年 12 月 30 日に行われたため、遅くはありません。10002 に別の作業があり、完了日が期日よりも遅いことは関係ありません。その結果、Joe には 2 つの作業指示書と 1 つの遅れた作業指示書があります。

(また、worktodo では、workorder が主キーであると仮定します)。

4

1 に答える 1

1

SUM(CASE comparison THEN 1 ELSE 0 END) を使用して、比較が真であるすべてのケースを合計できます。このような。私は、特定の作業指示書に対して 1 つの作業完了レコードしか存在しないと仮定しています。

SELECT worktodo.worker, COUNT(worktodo.workorder) AS TotalWorkToDo,
    SUM(CASE WHEN (workdone.workorder IS NULL AND duedate < getdate() )
        OR donedate > duedate
    THEN 1 ELSE 0 END) AS TotalLateWorkToDo
FROM worktodo
LEFT OUTER JOIN workdone
    ON worktodo.workorder = workdone.workorder
GROUP BY worktodo.worker

特定の作業指示書に対して複数の作業完了レコードがある場合。

SELECT worktodo.worker, COUNT(worktodo.workorder) AS TotalWorkToDo,
    SUM(CASE WHEN (workdone.workorder IS NULL AND duedate < getdate() )
        OR donedate > duedate
    THEN 1 ELSE 0 END) AS TotalLateWorkToDo
FROM worktodo
LEFT OUTER JOIN 
    (SELECT workorder, min(donedate) AS donedate FROM workdone
        GROUP BY workorder) as workdone
    ON worktodo.workorder = workdone.workorder
GROUP BY worktodo.worker
于 2013-05-21T21:33:05.313 に答える