我想计算每年员工的工资。假设一名员工自2016年7月起在公司工作1。5年,我想分别以2016年和2017年的薪资两行显示记录。如果月薪为20000
,那么对于18 months
,这就是应该如何显示结果。
EmpID Year MonthlySalary YearlySalary TotalSalary
1 2016 20000 120000 120000 (because was hired in jul)
1 2017 20000 240000 360000
2 2017 18000 216000 216000
我有一个查询,计算每月工资,年份和总工资。我用月计算总薪水。
CREATE TABLE EmployeeInfo (
EmpID Int,
FirstName Varchar(25),
LastName Varchar(25),
MonthlySalary Int,
DOJ Date);
INSERT INTO EmployeeInfo VALUES (1, 'Ahmad', 'Usman', '20000', '2016-06-01');
INSERT INTO EmployeeInfo VALUES (2, 'Erick', 'Ortiz', '18000', '2017-01-01');
SELECT [EmployeeName] = [EI].[FirstName] + ' ' + [EI].[LastName],
[EI].[DOJ],
[MonthlySalary] = [EI].MonthlySalary,
[EXPERIENCE] = ( CONVERT(VARCHAR(2), Datediff(YEAR, [DOJ], Getdate())) ),
[TotalSalary] = ( ( CONVERT(VARCHAR(2), Datediff(MONTH, [DOJ], Getdate())) ) * ( Isnull(NULL, [EI].MonthlySalary) ) )
FROM [EmployeeInfo] [EI]
答案 0 :(得分:1)
你需要一个日历表来执行此操作,我使用递归cte来生成日期。
;WITH cte
AS (SELECT EmpID, FirstName, LastName, MonthlySalary, DOJ, cntr = 1, SalaryMonth = DOJ
FROM EmployeeInfo
UNION ALL
SELECT e.EmpID, e.FirstName, e.LastName, e.MonthlySalary, e.DOJ, cntr = cntr + 1, Dateadd(month, cntr, e.DOJ)
FROM cte c
JOIN EmployeeInfo e
ON c.EmpID = e.EmpID
WHERE Dateadd(month, cntr, e.DOJ) < DATEADD(dd,-(DAY(Getdate())),Getdate()))
SELECT EmpID,
[Year] = Year(SalaryMonth),
MonthlySalary,
YearlySalary = Sum(MonthlySalary),
TotalSalary = Sum(Sum(MonthlySalary)) OVER(partition BY EmpID ORDER BY Year(SalaryMonth))
FROM cte
GROUP BY EmpID, Year(SalaryMonth), MonthlySalary
OPTION (MAXRECURSION 0)
答案 1 :(得分:1)
尝试递归CTE。喜欢这个
;WITH CTE
AS
(
SELECT
EmpId,
EmpYr = YEAR(DOJ),
Month = 12-CASE WHEN MONTH(DOJ) = 1 THEN 0 ELSE MONTH(DOJ) END,
MonthlySalary,
YearlySalary = MonthlySalary*(12-CASE WHEN MONTH(DOJ) = 1 THEN 0 ELSE MONTH(DOJ) END),
TotalSal = MonthlySalary*(12-CASE WHEN MONTH(DOJ) = 1 THEN 0 ELSE MONTH(DOJ) END)
FROM EmployeeInfo
UNION ALL
SELECT
EmpId,
EmpYr = EmpYr+1,
Month = 12,
MonthlySalary,
YearlySalary = MonthlySalary*
(
CASE WHEN EmpYr = YEAR(GETDATE())
THEN MONTH(GETDATE())
ELSE 12 END
),
TotalSal = TotalSal+(MonthlySalary*
(
CASE WHEN EmpYr = YEAR(GETDATE())
THEN MONTH(GETDATE())
ELSE 12 END
))
FROM CTE
WHERE EmpYr < YEAR(GETDATE())
)
SELECT
EmpId,
EmpYr,
MonthlySalary,
YearlySalary,
TotalSalary = TotalSal
FROM CTE
ORDER BY EmpId
我的结果
检查DEMO
答案 2 :(得分:0)
with sy as (
Select EmpId, year(DOJ) cyear, FirstName+' '+LastName AS EmployeeName,
avg(MonthlySalary) MonthlySalary, sum(MonthlySalary) YearlySalary, avg(MonthlySalary)*12 TotalSalary
FROM EmployeeInfo
group by year(DOJ),FirstName+' '+LastName, EmpID
)
select sy1.EmpId, sy1.cyear, sy1.EmployeeName, sy1.MonthlySalary MonthlySalary, sy1.YearlySalary, sum(sy2.YearlySalary) TotalSalary from
sy sy1, sy sy2
where sy1.EmpId = sy2.EmpId and sy1.EmployeeName = sy2.EmployeeName and sy1.cyear >= sy2.cyear
group by sy1.EmpId, sy1.cyear, sy1.EmployeeName, sy1.YearlySalary,sy1.MonthlySalary
(EmpId补充)
答案 3 :(得分:0)
您可以制作一个简单的参考表,然后进行连接。
注意:“Sum(....)OVER(....)”仅适用于SQL Server 2012或更高版本。
WITH REF ( YY ) AS (
SELECT 2017 --OR USE THE LATEST YEAR PREFERRED.
UNION ALL
SELECT YY - 1
FROM REF
WHERE REF.YY > 1950 -- SET THE EARLIEST YEAR
)
SELECT
EI.EmpID,
REF.YY AS [Year],
EI.MonthlySalary,
CASE WHEN REF.YY = YEAR(DOJ) THEN MonthlySalary*(13-MONTH(DOJ))
ELSE MonthlySalary * 12 END AS YearlySalary,
SUM (CASE WHEN REF.YY = YEAR(DOJ) THEN MonthlySalary*(13-MONTH(DOJ))
ELSE MonthlySalary * 12 END ) OVER (PARTITION BY EMPID ORDER BY REF.YY) TotalSalary
FROM [EmployeeInfo] [EI]
JOIN
REF
ON
YEAR(DOJ) <= YY
ORDER BY
EI.EMPID, REF.YY
;