2

したがって、次の形式でデータをテーブルにインポートしています(呼び出しはRAWDATAです):

EMPID  | STARTDATE  | ENDDATE    | TOTALHOURS | TOTALWAGES
ABC123 | 01-01-2013 | 01-28-2013 | 160.0      | 1800.00
XYZ987 | 01-01-2013 | 01-31-2013 | 200.0      | 2500.00

そのデータを取得して、別のテーブル (EMPDATA) に次の形式で配置する必要があります。

エンピッド | 日付 | 営業時間 | 賃金
ABC123 | 2013 年 1 月 1 日 | 5.71 | 64.29
ABC123 | 2013 年 1 月 2 日 | 5.71 | 64.29
ABC123 | 2013 年 1 月 3 日 | 5.71 | 64.29
…… | ………… | .... | .....
XYZ987 | 2013 年 1 月 1 日 | 6.45 | 80.66
XYZ987 | 2013 年 1 月 2 日 | 6.45 | 80.66
XYZ987 | 2013 年 1 月 3 日 | 6.45 | 80.66
…… | ………… | .... | .....

私の考えでは、STARTDATE と ENDDATE の間に DATEDIFF を実行して、時間と賃金を分散する日数 (この場合は 28) を計算し、1 日あたりの平均労働時間と賃金を含む行を挿入します。 . これはすべて、RAWDATA テーブルのトリガーで行われます。トリガーで STARTDATE から ENDDATE まで反復する方法がわかりません。

編集: また、インポートされるデータの各行の開始日/終了日が常に同じであるとは限らないことも述べておく必要があります。これを示すために、最初の表の例を更新しました。

4

2 に答える 2

5
  1. dateテーブルを作成し、を使用しJOINます。
  2. startdate~の間の日数を計算するenddate
  3. totalhourstotalwages計算された日数で割ります。

これが私の解決策です:

SELECT a.empid, b.dd AS date, 
  CAST(a.totalhours AS decimal) / (DATEDIFF(day, startdate, enddate) + 1) AS hours,
  CAST(a.totalwages AS decimal) / (DATEDIFF(day, startdate, enddate) + 1) AS wages
FROM wages a
INNER JOIN dates b ON dd BETWEEN a.startdate AND a.enddate

結果

| | エンピッド | 日付 | 営業時間 | 賃金 |
-------------------------------------------------- ------
| | ABC123 | 2013-01-01 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-02 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-03 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-04 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-05 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-06 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-07 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-08 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-09 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-10 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-11 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-12 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-13 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-14 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-15 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-16 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-17 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-18 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-19 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-20 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-21 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-22 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-23 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-24 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-25 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-26 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-27 | 5.71428571428 | 64.28571428571 |
| | ABC123 | 2013-01-28 | 5.71428571428 | 64.28571428571 |

デモを見る

于 2013-03-29T14:23:52.320 に答える
0

SQL Server 2005 以降を使用していると仮定すると、Recursive CTEこれに a を使用して動的な日付範囲を作成できます (ルックアップ テーブルを使用する場合と比べて)。これはGROUP BYempid フィールドを使用し、empid ごとに 1 つの行を想定しています。

WITH RecCTE AS (
  SELECT empid, startdate
  FROM rawdata
  UNION ALL
  SELECT R.empid, DATEADD(day,1,R.startdate)
  FROM RecCTE R JOIN rawdata RD ON R.startdate < RD.enddate
  )
INSERT INTO EMPDATA 
SELECT R.EmpId, R.StartDate, T.TotalHours/R2.cnt, T.TotalWages/R2.cnt
FROM RecCTE R
  JOIN (SELECT empid, totalhours, totalwages
        FROM rawdata
       ) T ON R.empid = T.empid
  JOIN (SELECT EmpID, COUNT(*) cnt 
        FROM RecCTE 
        GROUP BY EmpID) R2 ON R.EmpID=R2.EmpId

SQL フィドルのデモ

これをもう少し効率的にする方法があるかもしれませんが、これで正しい方向に進むはずです。たとえば、COUNT OVER関数を使用してサブクエリに対するカウントを返すことができます。

WITH RecCTE AS (
  SELECT empid, startdate
  FROM rawdata
  UNION ALL
  SELECT R.empid, DATEADD(day,1,R.startdate)
  FROM RecCTE R JOIN rawdata RD ON R.startdate < RD.enddate
  )
INSERT INTO EMPDATA 
SELECT R.EmpId, R.StartDate, 
    T.TotalHours/COUNT(1) OVER (PARTITION BY R.EmpId), 
    T.TotalWages/COUNT(1) OVER (PARTITION BY R.EmpId)
FROM RecCTE R
  JOIN (SELECT empid, totalhours, totalwages
        FROM rawdata
       ) T ON R.empid = T.empid
ORDER BY R.StartDate
于 2013-03-29T14:32:52.777 に答える