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) 中:

EMPID | 日期 | 小时 | 工资
ABC123 | 01-01-2013 | 5.71 | 64.29
ABC123 | 01-02-2013 | 5.71 | 64.29
ABC123 | 01-03-2013 | 5.71 | 64.29
...... | .......... | .... | ......
XYZ987 | 01-01-2013 | 6.45 | 80.66
XYZ987 | 01-02-2013 | 6.45 | 80.66
XYZ987 | 01-03-2013 | 6.45 | 80.66
...... | .......... | .... | ......

我的想法是在 STARTDATE 和 ENDDATE 之间做一个 DATEDIFF 来计算多少天(在这种情况下:28)来分配小时数和工资,然后对于每一天,插入一行包含每天工作的平均小时数和工资. 这一切都将通过 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

结果

| EMPID | 日期 | 小时 | 工资 |
-------------------------------------------------- ------
| 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 有一行:

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 回答