我想计算一名员工在为公司工作期间每月的平均收入。
我基于类似的线程构建了一个递归CTE,我只得到一个员工的结果。我需要做什么样的修改才能使员工ID变量并为表中的每个员工获得相同类型的结果?
这是我的代码:
DECLARE @tbl AS TABLE
(
ID VARCHAR(50) ,
Earning FLOAT,
StartDate DATE ,
EndDate DATE
)INSERT INTO @tbl
( ID, Earning, StartDate, EndDate
SELECT employee_ID AS ID
,([Total Earning]/ (SELECT datediff(MONTH,[EndDate],
[StartDate])+1
FROM [employee_table] WHERE employee_ID = 'EKA-0004562'))
,[StarTDate]
,[EndDate]
FROM [employee_table]
WHERE employee_ID = 'EKA-0004562'
--final query using recursive cte
;
WITH cte
AS ( SELECT T.ID ,
T.Earning ,
T.StartDate ,
T.EndDatum ,
CONVERT(DATE, NULL) AS Dt ,
n = 0
FROM @tbl AS T
UNION ALL
SELECT cte.ID ,
cte.Earning ,
cte.StartDate ,
cte.EndDatum ,
DATEADD(MONTH, n, cte.StartDate) ,
cte.n + 1
FROM cte
WHERE n <= DATEDIFF(MONTH, cte.StartDate, cte.EndDatum)
)
SELECT cte.ID ,
cte.Earning,
dt AS Months
FROM cte
WHERE cte.Dt IS NOT NULL
这是我的目标:
好吧,我有一张包含大量数据的表格,其中包含有关员工的信息。 每个员工都有一个&#34; startdate&#34; (他开始为公司工作的时间)和&#34; enddate&#34; (他辞职的时候)。 我想在一个表中写入与员工在一个月内为公司工作的行数相同的行数。例如:
我的基本表:
Employee Number | StartDate | EndDate | Total Earnings (Total Earnings/(EndDate-StartDate)
4711 20150101 20150523 24110
此示例显示该员工为公司工作了5个月并获得了24110欧元。在Avarage,他每月赚4822欧元。 所以我想在新表中插入5行,其中包含以下信息:
新表:
Employee Number | StartDate | EndDate | AVG Earnings
row1: 4711 20150101 20150523 4822
row2: 4711 20150201 20150523 4822
row3: 4711 20150301 20150523 4822
row4: 4711 20150401 20150523 4822
row5: 4711 20150501 20150523 4822
答案 0 :(得分:0)
我可能错了,但我认为你的查询看起来过于复杂,不需要递归CTE。在与很多员工打交道并连续几年时,这可能会变得不合适。
此查询为2个示例用户提供正确的输出:
样品
declare @employee_table table(Employee_Number int, StartDate date, EndDate date, Total_Earnings bigint);
Insert Into @employee_table(Employee_Number, StartDate, EndDate, Total_Earnings) values
(4711, '20150101', '20150523', 24110)
, (4712, '20150101', '20150423', 24110);
查询
with list(n) as (
Select ROW_NUMBER() over(Order By n)
From (
Select 1 From (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as l1(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as l2(n)
Cross Join (values(1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) as l3(n)
) as l(n)
)
Select l.n, e.Employee_Number
, [StartDate] = DATEADD(MONTH, l.n-1, e.StartDate)
, [EndDate] = e.EndDate
, [AVG Earnings] = e.Total_Earnings/(DATEDIFF(MONTH, e.StartDate, e.EndDate)+1)
From @employee_table as e
Inner Join list as l on l.n <= DATEDIFF(MONTH, e.StartDate, e.EndDate)+1
Order By e.Employee_Number, l.n
输出
n Employee_Number StartDate EndDate AVG Earnings
1 4711 2015-01-01 2015-05-23 4822
2 4711 2015-02-01 2015-05-23 4822
3 4711 2015-03-01 2015-05-23 4822
4 4711 2015-04-01 2015-05-23 4822
5 4711 2015-05-01 2015-05-23 4822
1 4712 2015-01-01 2015-04-23 6027
2 4712 2015-02-01 2015-04-23 6027
3 4712 2015-03-01 2015-04-23 6027
4 4712 2015-04-01 2015-04-23 6027
注释:
答案 1 :(得分:0)
你走了:
示例数据
create table #test
(
ID INT,
StartDate DATE,
EndDatum DATE,
Earning INT
)
insert into #test values
(4711,'20150101','20150523',24110),
(4712,'20150101','20150625',32550)
QUERY
--final query using recursive cte
;
WITH cte
AS ( SELECT T.ID ,
T.Earning ,
T.StartDate ,
T.EndDatum ,
CONVERT(DATE, NULL) AS Dt ,
n = 0
FROM #test AS T
UNION ALL
SELECT cte.ID ,
cte.Earning ,
cte.StartDate ,
cte.EndDatum ,
DATEADD(MONTH, n, cte.StartDate) ,
cte.n + 1
FROM cte
WHERE n <= DATEDIFF(MONTH, cte.StartDate, cte.EndDatum)
)
SELECT cte.ID ,
dt StartDate,
cte.EndDatum EndDate,
cte.Earning / ((DATEDIFF(MONTH, cte.StartDate, cte.EndDatum)) +1) [AVG Earnings]
FROM cte
WHERE cte.Dt IS NOT NULL
<强>输出强>
ID StartDate EndDate AVG Earnings
4712 2015-01-01 2015-06-25 5425
4712 2015-02-01 2015-06-25 5425
4712 2015-03-01 2015-06-25 5425
4712 2015-04-01 2015-06-25 5425
4712 2015-05-01 2015-06-25 5425
4712 2015-06-01 2015-06-25 5425
4711 2015-01-01 2015-05-23 4822
4711 2015-02-01 2015-05-23 4822
4711 2015-03-01 2015-05-23 4822
4711 2015-04-01 2015-05-23 4822
4711 2015-05-01 2015-05-23 4822