如何获得每周特定类型的天数

时间:2016-04-21 07:55:20

标签: sql sql-server date sql-server-2012

如果我有这样的表:

trans_date

鉴于每位员工必须在day_type =3中拥有所有月份日。

如何让所有员工在一年中的某个月至少一周内超过两个p x p

3 个答案:

答案 0 :(得分:2)

鉴于您提供的数据:

declare  @table1 table (emp_num int, trans_date datetime, day_type int)
insert into @table1
VALUES (5667,'2016-03-01',1),(5667,'2016-03-02',1),(5667,'2016-03-03',1),
(5667,'2016-03-04',3),(5667,'2016-03-05',3),(5667,'2016-03-06',1),
(5667,'2016-03-07',1),(5667,'2016-03-08',1),(5667,'2016-03-09',1),
(5667,'2016-03-10',1),(5667,'2016-03-11',3),(5667,'2016-03-12',3),
(5667,'2016-03-13',1),(5667,'2016-03-14',1),(5667,'2016-03-15',1),
(5667,'2016-03-16',1),(5667,'2016-03-17',1),(5667,'2016-03-18',3),
(5667,'2016-03-19',3),(5667,'2016-03-20',1),(5667,'2016-03-21',1),
(5667,'2016-03-22',1),(5667,'2016-03-23',1),(5667,'2016-03-24',1),
(5667,'2016-03-25',3),(5667,'2016-03-26',3),(5667,'2016-03-27',1),
(5667,'2016-03-28',1),(5667,'2016-03-29',1),(5667,'2016-03-30',1),
(5667,'2016-03-31',1),(4275,'2016-03-01',3),(4275,'2016-03-02',1),
(4275,'2016-03-03',1 ),(4275,'2016-03-04',3 ),(4275,'2016-03-05',1 ),
(4275,'2016-03-06',1 ),(4275,'2016-03-07',3 ),(4275,'2016-03-08',3 ),
(4275,'2016-03-09',1 ),(4275,'2016-03-10',1 ),(4275,'2016-03-11',3 ),
(4275,'2016-03-12',1 ),(4275,'2016-03-13',1 ),(4275,'2016-03-14',3 ),
(4275,'2016-03-15',3 ),(4275,'2016-03-16',1 ),(4275,'2016-03-17',1 ),
(4275,'2016-03-18',3 ),(4275,'2016-03-19',1 ),(4275,'2016-03-20',1 ),
(4275,'2016-03-21',3 ),(4275,'2016-03-22',3 ),(4275,'2016-03-23',1 ),
(4275,'2016-03-24',1),(4275,'2016-03-25',3 ),(4275,'2016-03-26',1 ),
(4275,'2016-03-27',1 ),(4275,'2016-03-28',3 ),(4275,'2016-03-29',3 ),
(4275,'2016-03-30',1 ),(4275,'2016-03-31',1)

这将为您提供所需的信息(emp_num 5667未返回,emp_num 4275已退回),但请记住,有些月份的周数将超过两个月,因此您可能需要调整如果您对此的要求更加微妙:

 declare @year int = 2016,
 @month int = 3

 ;with emp_cte (emp_num, weeknum, day_type_count)
 as
 (
     select emp_num, 
         datepart(week, trans_date), 
         sum(case when day_type = 3 then 1 else 0 end)
     from @table1 t
     where year(trans_date) = @year
     and month(trans_date) = @month
     group by emp_num, datepart(week, trans_date)
 )

 select emp_num
 from emp_cte
 group by emp_num
 having min(day_type_count) >= 2

答案 1 :(得分:1)

下面的内容。 DATEADD(month, DATEDIFF(month, 0, trans_date), 0)会将日期转换为“本月的第一天”,然后EOMONTH将“月末”,有效地限制您的“给定月份”(@GIVEN_MONTH_DATE)。< / p>

DECLARE @GIVEN_MONTH_DATE DATE = '2016-04-01'
DECLARE @WEEKS_IN_MONTH = DATEDIFF(week, DATEADD(month, DATEDIFF(month, 0, @GIVEN_MONTH_DATE), 0), EOMONTH(@GIVEN_MONTH_DATE))

WITH results AS (
    SELECT
        emp_num AS EmployeeNumber,
        DATEPART(week, trans_date) AS Week,
        day_type AS DayType,
        COUNT(emp_num) AS Total
    FROM
        table
    WHERE
        day_type = 3
        AND trans_date BETWEEN DATEADD(month, DATEDIFF(month, 0, @GIVEN_MONTH_DATE), 0) AND EOMONTH(@GIVEN_MONTH_DATE)
    GROUP BY
        emp_num,
        DATEPART(week, trans_date),
        day_type
    HAVING
        COUNT(emp_num) > 2
)

SELECT
    EmployeeNumber,
    SUM(Total) AS Transactions
FROM
    results
GROUP BY
    EmployeeNumber
HAVING
    COUNT(EmployeeNumber) = @WEEKS_IN_MONTH

答案 2 :(得分:1)

DECLARE @month int = 3,
        @year int = 2016

;WITH cte AS (
SELECT *
FROM (VALUES
                        (5667, '2016-03-01', 1),(5667, '2016-03-02', 1),(5667, '2016-03-03', 1),(5667, '2016-03-04', 3),(5667, '2016-03-05', 3),(5667, '2016-03-06', 1), --2
(5667, '2016-03-07', 1),(5667, '2016-03-08', 1),(5667, '2016-03-09', 1),(5667, '2016-03-10', 1),(5667, '2016-03-11', 3),(5667, '2016-03-12', 3),(5667, '2016-03-13', 1), --2
(5667, '2016-03-14', 1),(5667, '2016-03-15', 1),(5667, '2016-03-16', 1),(5667, '2016-03-17', 1),(5667, '2016-03-18', 3),(5667, '2016-03-19', 3),(5667, '2016-03-20', 1), --2
(5667, '2016-03-21', 1),(5667, '2016-03-22', 1),(5667, '2016-03-23', 1),(5667, '2016-03-24', 1),(5667, '2016-03-25', 3),(5667, '2016-03-26', 3),(5667, '2016-03-27', 1), --2
(5667, '2016-03-28', 1),(5667, '2016-03-29', 1),(5667, '2016-03-30', 1),(5667, '2016-03-31', 1),                                                                         --0

                        (4275, '2016-03-01', 3),(4275, '2016-03-02', 1),(4275, '2016-03-03', 1),(4275, '2016-03-04', 3),(4275, '2016-03-05', 1),(4275, '2016-03-06', 3), --3
(4275, '2016-03-07', 3),(4275, '2016-03-08', 3),(4275, '2016-03-09', 1),(4275, '2016-03-10', 1),(4275, '2016-03-11', 3),(4275, '2016-03-12', 1),(4275, '2016-03-13', 1), --3
(4275, '2016-03-14', 3),(4275, '2016-03-15', 3),(4275, '2016-03-16', 1),(4275, '2016-03-17', 1),(4275, '2016-03-18', 3),(4275, '2016-03-19', 1),(4275, '2016-03-20', 1), --3
(4275, '2016-03-21', 3),(4275, '2016-03-22', 3),(4275, '2016-03-23', 1),(4275, '2016-03-24', 1),(4275, '2016-03-25', 3),(4275, '2016-03-26', 1),(4275, '2016-03-27', 1), --3
(4275, '2016-03-28', 3),(4275, '2016-03-29', 3),(4275, '2016-03-30', 1),(4275, '2016-03-31', 1),                                                                         --2

                        (9922, '2016-03-01', 1),(9922, '2016-03-02', 1),(9922, '2016-03-03', 1),(9922, '2016-03-04', 3),(9922, '2016-03-05', 3),(9922, '2016-03-06', 1), --2
(9922, '2016-03-07', 1),(9922, '2016-03-08', 1),(9922, '2016-03-09', 1),(9922, '2016-03-10', 1),(9922, '2016-03-11', 3),(9922, '2016-03-12', 3),(9922, '2016-03-13', 1), --2
(9922, '2016-03-14', 1),(9922, '2016-03-15', 1),(9922, '2016-03-16', 1),(9922, '2016-03-17', 1),(9922, '2016-03-18', 3),(9922, '2016-03-19', 3),(9922, '2016-03-20', 1), --2
(9922, '2016-03-21', 3),(9922, '2016-03-22', 3),(9922, '2016-03-23', 1),(9922, '2016-03-24', 1),(9922, '2016-03-25', 1),(9922, '2016-03-26', 1),(9922, '2016-03-27', 1), --2
(9922, '2016-03-28', 3),(9922, '2016-03-29', 1),(9922, '2016-03-30', 3),(9922, '2016-03-31', 1)                                                                          --2
) AS t (emp_num, trans_date, day_type)
)
,final AS (
SELECT  DATEPART(week,c.trans_date) as week_num,
        emp_num,
        COUNT(c.trans_date) as coun
FROM cte c 
WHERE day_type = 3 
    AND DATEPART(month,trans_date) = @month
    AND DATEPART(YEAR,trans_date) = @year
GROUP BY emp_num,
        DATEPART(week,c.trans_date)
HAVING COUNT(c.trans_date) > 2
)

SELECT f.emp_num
FROM final f
GROUP BY emp_num

输出:

emp_num
-----------
4275

(1 row(s) affected)