按年计算工资

时间:2018-01-14 13:34:26

标签: sql sql-server

我想计算每年员工的工资。假设一名员工自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] 

4 个答案:

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

我的结果

enter image description here

检查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
;