2

私は多くの同様の質問を読みましたが、私の特定のケースは、私が見つけた他のほとんどの状況よりも少し単純でありながら複雑です. 質問は次のとおりです。

ユーザーの出勤と退勤の日付/時刻スタンプを含む労働トランザクションのテーブルがあります。各トランザクション (行) には、ユーザー名、開始時間と終了時間、合計時間数、および "タグ" (通常は作業指示書番号) があります。

休日の場合、開始時間と終了時間のないトランザクションを各ユーザーに追加します。合計時間数は 8、タグは「HOLIDAY」です。以下の表のサンプルを作成しました。

USER   | STARTDATE | STARTTIME | STOPDATE | STOPTIME | HOURS | TAG
JSMITH | 7/2/12    | 9:00AM    | 7/2/12   | 5:00PM   | 8     | WO12345
JSMITH | 7/3/12    | 9:00AM    | 7/3/12   | 5:00PM   | 8     | WO13579
JSMITH | 7/4/12    | NULL      | 7/4/12   | NULL     | 8     | HOLIDAY
JSMITH | 7/5/12    | 9:00AM    | 7/5/12   | 5:00PM   | 8     | WO24680
JSMITH | 7/6/12    | 9:00AM    | 7/6/12   | 5:00PM   | 8     | WO98765

これが問題です。ユーザーは、キーワードが BUSINESS 日である 2 営業日前に働いた場合にのみ、8 時間の休暇を取得することになっています。休暇日 (VACATION のタグが付いている) は、「勤務中」と見なされます。したがって、基本的に、2日前のそれぞれに労働取引があれば、休暇の資格があります。

さらに複雑なことに、月曜日から金曜日までが典型的な週の労働時間ですが、人々は土曜日に働くことができます (ただし必須ではありません)。したがって、休日が月曜日に当たる場合、彼らは木/金または金/土のいずれかで働くことができます。休日の資格を得るため。

このレポートは週に 1 回 (月曜日に) 実行され、前の週を参照します。したがって、私の思考プロセスは、Holiday のタグが付いた取引を探し、毎日の取引について 2 "営業" 日前に確認することです。1 日または両方の日にトランザクションが見つからない場合は、ユーザーまたは完全な休日の行を返して、資格がないことを示します (最終的な結果セットは、休日の資格がないトランザクションまたはユーザーのリストである必要があります)。

前の 2 日間を確認するか、「営業」日 (土曜日を含む可能性がある) を決定するためのすべての助けをいただければ幸いです。また、詳細が必要な場合はお知らせください。

ありがとう!

4

2 に答える 2

0

この種のロジックは、SQLで読みやすくパフォーマンスの高い方法で表現するのが難しくなります。多くの場合、データが非常に少ないため、ファクトテーブルを作成する方が簡単です。このようにして、このファクトテーブルに対して結合することができます。あなたのテーブルが何と呼ばれているのかわからなかったので、単に「ログ」と呼びました。

私はこのコードがあなたが望むことをするだろうと信じています。

アップデート

金/土は許可されるが木/土は許可されないという制限を考慮して、許可される組み合わせを含めるようにファクトテーブルを修正しました。有効な組み合わせごとに、(休日の)平日の新しい行と2つの許可されたオフセットを指定します。月曜日(米国では平日2)に、(-2、-3)と(-3、-4)の2つのペアを指定します。これは、それぞれ金/土と木/金を意味します。

新しいコード:

-- Create a facts table. This would maybe not be a temp table in the final solution but
-- rather a static, indexed table. 

CREATE TABLE #validdays (
   forday int,
   validday1 int, -- offset from 'forday'
   validday2 int  -- offset from 'forday'
)
-- For each weekday, give the allowed combinations of work days
INSERT INTO #validdays values (2,-2,-3)
INSERT INTO #validdays values (2,-3,-4)
INSERT INTO #validdays values (6,-1,-2)
INSERT INTO #validdays values (5,-1,-2)
INSERT INTO #validdays values (4,-1,-2)
INSERT INTO #validdays values (3,-1,-3)
INSERT INTO #validdays values (3,-1,-4)

SELECT * 
FROM Log l
WHERE 
   l.TAG = 'HOLIDAY' AND
   NOT EXISTS 
   (SELECT *
    FROM #validdays v 
    INNER JOIN Log vl ON vl.[USER] = l.[USER] AND 
                         vl.startdate = DATEADD(day, v.validday1, l.startdate) AND
                         vl.tag <> 'HOLIDAY'
    INNER JOIN Log vl2 ON vl2.[USER] = l.[USER] AND 
                          vl2.startdate = DATEADD(day, v.validday2, l.startdate) AND
                          vl2.tag <> 'HOLIDAY'
    WHERE v.forday = datepart(dw,l.startdate)
   )
   -- Any restrictions about periodicity, i.e. check that l.startdate is within last week.
drop table #validdays
于 2012-11-20T21:02:27.157 に答える
0

これから始めましょう。

SELECT a.[STARTDATE] 'Begin Date', a.[TAG] AS 'Begin Tag', 
  b.[TAG] AS '1 Day Before', c.[TAG] AS '2 Days Before',
  d.[TAG] AS '3 Days Before',  e.[TAG] AS '4 Days Before',
  f.[TAG] AS '5 Days Before'
FROM tx a
LEFT JOIN tx b ON b.[USER] = a.[USER] 
  AND b.[STARTDATE] = DATEADD (day, -1, a.[STARTDATE])
LEFT JOIN tx c ON c.[USER] = a.[USER] 
  AND c.[STARTDATE] = DATEADD (day, -2, a.[STARTDATE])
LEFT JOIN tx d ON d.[USER] = a.[USER] 
  AND d.[STARTDATE] = DATEADD (day, -3, a.[STARTDATE])
LEFT JOIN tx e ON e.[USER] = a.[USER] 
  AND e.[STARTDATE] = DATEADD (day, -4, a.[STARTDATE])
LEFT JOIN tx f ON f.[USER] = a.[USER] 
  AND f.[STARTDATE] = DATEADD (day, -5, a.[STARTDATE])
WHERE a.[STARTDATE] = '2012-07-05'

これにより、過去5日間(日付別)のタグが表示されます。

開始日開始タグ1日前2日前3日前4日前5日前
---------- --------- ------------ ------------- ------ ------- ------------- -------------
2012-07-05 WO98765 WO24680 HOLIDAY WO13579 WO12345 NULL

次に、過去2日間が休日以外の作業タグであるかどうかを確認するロジックを追加します。

于 2012-11-20T20:40:48.723 に答える