SQL |添加特定金额并在单独的列

时间:2015-11-26 00:08:09

标签: sql sql-server tsql

我正在尝试实现一个SQL查询,我需要将每周,每月,每年雇用的特定数量的员工相加,并将其显示在命名列中。因此,即每周雇用总人数,每月雇用总人数,年度雇用总人数。

加入两个表。一个是简单的表格,列出自1-1-1900到12-31-2099之间的每一天。另一个是简单的员工数据库,列出了他们的雇佣日期。

添加解释将有助于我学习SQL逻辑,并将是一个加号。

我在下面给出了查询,输出也在图片中:

如果我没有清楚地解释我的问题,请提出建议,我会尝试重述我的问题。

查询:

DECLARE      @STARTDATE DATETIME,
             @ENDDATE DATETIME

SET          @STARTDATE = '1989-12-31' --  >=
SET          @ENDDATE = '2015-10-31 23:59:59' -- <

SELECT       c.calendarDate,
             Count(e.empid) as Number_Hired,
             datepart(week,c.calendarDate) as Week,
             datepart(month,c.calendarDate) as Month,
             datepart(year,c.calendarDate) as Year


FROM         intranet.dbo.igbl_calendar c

LEFT JOIN    intranet.dbo.iemp_employee e on CONVERT(DATE, c.calendarDate) = CONVERT(DATE, e.hireDate) and aliasID = 'P'

WHERE        c.calendarDate BETWEEN @STARTDATE AND @ENDDATE

GROUP BY     c.calendarDate

ORDER BY     c.calendarDate

2 个答案:

答案 0 :(得分:0)

假设你要做的就是在当前查询中添加3个额外的列,你可以留下加入内联视图或CTE来执行周,月,年的个别计数。

e.g。

DECLARE @STARTDATE DATETIME = '1989-12-31'
    , @ENDDATE DATETIME = '2015-10-31 23:59:59'

SELECT
     c.calendarDate,
     Count(e.empid) as Number_Hired,
     datepart(week, c.calendarDate) as [Week],
     datepart(month, c.calendarDate) as [Month],
     datepart(year, c.calendarDate) as [Year],
     ew.WeekCount Number_Hired_This_Week,
     em.MonthCount Number_Hired_This_Month,
     ey.YearCount Number_Hired_This_Year
FROM
    intranet.dbo.igbl_calendar c
    LEFT JOIN intranet.dbo.iemp_employee e on c.calendarDate = e.hireDate AND aliasID = 'P'
    LEFT JOIN (SELECT DATEPART(ww, hireDate) [Week]
        , DATEPART(yy, hireDate) [Year]
        , COUNT(empid) [WeekCount]
        FROM intranet.dbo.iemp_employee
        GROUP BY DATEPART(ww, hireDate), DATEPART(yy, hireDate)) ew
        ON ew.[Week] = DATEPART(ww, c.calendarDate)
        AND ew.[Year] = DATEPART(yy, c.calendarDate)
    LEFT JOIN (SELECT DATEPART(mm, hireDate) [Month]
        , DATEPART(yy, hireDate) [Year]
        , COUNT(empid) [MonthCount]
        FROM intranet.dbo.iemp_employee
        GROUP BY DATEPART(mm, hireDate), DATEPART(yy, hireDate)) em
        ON em.[Month] = DATEPART(mm, c.calendarDate)
        AND em.[Year] = DATEPART(yy, c.calendarDate)
    LEFT JOIN (SELECT  DATEPART(yy, hireDate) [Year]
        , COUNT(empid) [YearCount]
        FROM intranet.dbo.iemp_employee
        GROUP BY DATEPART(yy, hireDate)) ey
        ON ey.[Year] = DATEPART(yy, c.calendarDate)
WHERE
    c.calendarDate BETWEEN @STARTDATE AND @ENDDATE
GROUP BY
    c.calendarDate, ew.WeekCount, em.MonthCount, ey.YearCount
ORDER BY
    c.calendarDate

基本逻辑是,您希望通过按年度分组(使用datepart here)查找一年的总数,通过按年份和月份对每个月的总数进行分组,以及通过分组对每周的总数进行分组一年又一周。然后根据年/月/周将它们连接回原始查询。

虽然老实说,我只是在单独的查询中执行它们,而不是将它们全部输出。

答案 1 :(得分:0)

我个人会在解决此类问题时尽量减少使用JOIN,因为KEY需要JOIN需要进一步处理datepart()。< / p>

我更喜欢使用嵌套的SELECT语句。

DECLARE      @STARTDATE DATETIME,
             @ENDDATE DATETIME

SET          @STARTDATE = '1989-12-31' --  >=
SET          @ENDDATE = '2015-10-31 23:59:59' -- <

WITH EmpData AS (
    SELECT  count(*) 'HireCount', 
            datepart(year, e.hireDate) 'HireYear',
            datepart(month, e.hireDate) 'HireMonth',
            datepart(week, e.hireDate) 'HireWeek'
    FROM    intranet.dbo.iemp_employee e
    WHERE   e.aliasID = 'P'
    GROUP BY datepart(year, e.hireDate), datepart(month, e.hireDate), datepart(week, e.hireDate)
)

SELECT
     datepart(year, c.calendarDate) AS Year,
     datepart(month, c.calendarDate) AS Month,
     datepart(week, c.calendarDate) AS Week,
     (SELECT sum(HireCount) FROM EmpData WHERE datepart(year, c.calendarDate) = HireYear) 'Year Hire Count',
     (SELECT sum(HireCount) FROM EmpData WHERE datepart(year, c.calendarDate) = HireYear AND datepart(month, c.calendarDate) = HireMonth) 'Month Hire Count',
     (SELECT sum(HireCount) FROM EmpData WHERE datepart(year, c.calendarDate) = HireYear AND datepart(month, c.calendarDate) = HireMonth AND datepart(week, c.calendarDate) = HireWeek) 'Week Hire Count'
FROM
    intranet.dbo.igbl_calendar c
WHERE
    c.calendarDate BETWEEN @STARTDATE AND @ENDDATE
GROUP BY
    datepart(year, c.calendarDate) as Year, datepart(month, c.calendarDate) as Month, datepart(week, c.calendarDate) as Week
ORDER BY
    1,2,3