在sql中找到去年同一周的计数

时间:2017-09-22 06:27:22

标签: sql sql-server

我使用以下查询根据过去5-6周的日期从表中查找计数,如下所示

BEGIN
    SET datefirst 1;
    DECLARE @BeginDate datetime= '2016-10-10' 
    SELECT 
        count(*) as Total
      , datepart(wk, DateCreated) as WeekNumber
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate
    FROM TABLESES
    WHERE   
        CONVERT(date,DateCreated) >= DATEADD(DAY, -42, @BeginDate) 
        AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, @BeginDate)
    GROUP BY      datepart(wk, DateCreated)
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)
    ORDER BY datepart(wk, DateCreated)
END

这将返回如下结果集:

    Total   WeekNumber  WeekStartDate   WeekEndDate
    51295   36          29.08.2016      04.09.2016
    48133   37          05.09.2016      11.09.2016
    38991   38          12.09.2016      18.09.2016
    38074   39          19.09.2016      25.09.2016
    37192   40          26.09.2016      02.10.2016
    20835   41          03.10.2016      09.10.2016
    23781   42          10.10.2016      16.10.2016            

现在我想在最后添加一列,并计算去年同一周的数量。

我可以在此查询中实现相同的功能吗?或者我应该为它写一个完全不同的查询?我该如何进行此查询?

4 个答案:

答案 0 :(得分:1)

您可以UNIONDATEDIFF一起使用,以获得前一年的相同内容:

SELECT 
        count(*) as Total
      , datepart(wk, DateCreated) as WeekNumber
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate
    FROM TABLESES
    WHERE   
        CONVERT(date,DateCreated) >= DATEADD(DAY, -42, @BeginDate) 
        AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, @BeginDate)
    GROUP BY      datepart(wk, DateCreated)
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)
UNION ALL
SELECT 
        count(*) as Total
      , datepart(wk, DATEDIFF(year,1,DateCreated )) as WeekNumber
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DATEDIFF(year,1,DateCreated ))/7,0),104) as WeekStartDate
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DATEDIFF(year,1,DateCreated ))/7,6),104) as WeekEndDate
    FROM TABLESES
    WHERE   
        CONVERT(date,DateCreated) >= DATEADD(DAY, -42, @BeginDate) 
        AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, @BeginDate)
    GROUP BY      datepart(wk, DATEDIFF(year,1,DateCreated ))
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DATEDIFF(year,1,DateCreated ))/7,0),104)
      , convert(VARCHAR(20),dateadd(week,datediff(day,0,DATEDIFF(year,1,DateCreated ))/7,6),104)
    ORDER BY datepart(wk, DATEDIFF(year,1,DateCreated ))

答案 1 :(得分:1)

将您的最终结果放到临时表中,然后执行以下操作:

请务必检查上一年的日期逻辑。但希望你得到逻辑。我没有测试你的“版本”是否正确,因为我已经写了,但我希望你能得到这个。

测试版的结果

enter image description here

测试版本:

DECLARE @Weeks1 TABLE(
Total int,
Weeknumber INT,
WeekStartDate nvarchar(50),
WeekEndDate nvarchar(50)
)

DECLARE @Weeks2 TABLE(
Total int,
Weeknumber INT,
WeekStartDate nvarchar(50),
WeekEndDate nvarchar(50) 
)


insert into @Weeks1 (Total,Weeknumber,WeekStartDate,Weekenddate)

values  ('51295', '36'        ,'29.08.2016'     ,'04.09.2016'),
    ('48133', '37'        ,'05.09.2016'     ,'11.09.2016'),
    ('38991', '38'        ,'12.09.2016'     ,'18.09.2016'),
    ('38074', '39'        ,'19.09.2016'     ,'25.09.2016'),
    ('37192', '40'        ,'26.09.2016'     ,'02.10.2016'),
    ('20835', '41'        ,'03.10.2016'     ,'09.10.2016'),
    ('23781', '42'        ,'10.10.2016'     ,'16.10.2016')


   insert into @Weeks2 (Total,Weeknumber,WeekStartDate,Weekenddate)

  values  ('324234', '36'       ,'29.08.2015'     ,'04.09.2015'),
    ('22333', '37'        ,'05.09.2015'     ,'11.09.2015'),
    ('23444', '38'        ,'12.09.2015'     ,'18.09.2015'),
    ('566666', '39'       ,'19.09.2015'     ,'25.09.2015'),
    ('4345', '40'         ,'26.09.2015'     ,'02.10.2015'),
    ('8657', '41'         ,'03.10.2015'     ,'09.10.2015'),
    ('8567567', '42'      ,'10.10.2015'     ,'16.10.2015')


Select a.Total,b.Total as 
LastYearTotal,a.Weeknumber,A.WeekStartDate,a.Weekenddate from @Weeks1 a 
inner join @Weeks2 b on a.Weeknumber = b.Weeknumber

使用您的版本:

DECLARE @Weeks1 TABLE(
Total int,
Weeknumber INT,
WeekStartDate nvarchar(50),
WeekEndDate nvarchar(50)
)

DECLARE @Weeks2 TABLE(
Total int,
Weeknumber INT,
WeekStartDate nvarchar(50),
WeekEndDate nvarchar(50)
)


BEGIN
SET datefirst 1;
DECLARE @BeginDate datetime= '2016-10-10' 

insert into @Weeks1 (Total,Weeknumber,WeekStartDate,Weekenddate)

SELECT 
    count(*) as Total
  , datepart(wk, DateCreated) as WeekNumber
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate
FROM TABLESES
WHERE   
    CONVERT(date,DateCreated) >= DATEADD(DAY, -42, @BeginDate) 
    AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, @BeginDate)
GROUP BY      datepart(wk, DateCreated)
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)
ORDER BY datepart(wk, DateCreated)
END



BEGIN
SET datefirst 1;
DECLARE @BeginDate2 datetime= '2015-10-10' 

insert into @Weeks2 (Total,Weeknumber,WeekStartDate,Weekenddate)

SELECT 
    count(*) as Total
  , datepart(wk, DateCreated) as WeekNumber
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate
FROM TABLESES
WHERE   
    CONVERT(date,DateCreated) >= DATEADD(DAY, -42, @BeginDate2) 
    AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, @BeginDate2)
GROUP BY      datepart(wk, DateCreated)
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)
ORDER BY datepart(wk, DateCreated)
END


Select a.Total,b.Total as 
LastYearTotal,a.Weeknumber,A.WeekStartDate,a.Weekenddate from @Weeks1 a 
inner join @Weeks2 b on a.Weeknumber = b.Weeknumber

答案 2 :(得分:1)

如果只有几周重要,您可以先进行一些日期计算并进行更简单的查询

SET datefirst 1;

 DECLARE @BeginDate datetime = '2016-10-10'; -- must be start of the week , <= last week -6
 declare @nweeks int = 6;
 -- this year interval
 declare @b1Date datetime = dateadd(week, -@nweeks , @BeginDate); --inclusive
 declare @e1Date datetime = dateadd(week, 1 , @BeginDate); -- exclusive
 declare @thisYear int = datepart(year, @b1Date);
 -- previous year interval
 declare @bwk int = datepart(week, @b1Date);
 declare @year2 datetime= dateadd(year,datediff(year,0,@b1Date)-1,0);
 declare @b2Date datetime = dateadd(week, @bwk-1, @year2);
 declare @e2Date datetime = dateadd(week, @bwk + @nweeks, @year2);
 -- check it
 select @BeginDate, @b1Date, @e1Date, @bwk,  @b2Date, @e2Date, datepart(week, @b2Date);

SELECT 
    count(case datepart(year, DateCreated) when @thisYear then 1 end) as TotalThisYear
  , datepart(wk, DateCreated) as WeekNumber
  , convert(VARCHAR(20),dateadd(week,datepart(week,DateCreated)-@bwk -1,@b1Date),104) as WeekStartDate
  , convert(VARCHAR(20),dateadd(day,7*(datepart(week,DateCreated)-@bwk-1)+6,@b1Date),104) as WeekEndDate
  , count(case datepart(year, DateCreated) when @thisYear-1 then 1 end) as TotalPrev
FROM TABLESES
WHERE   
    CONVERT(date,DateCreated) >= @b1Date AND CONVERT(date,DateCreated) <@e1Date
    OR
    CONVERT(date,DateCreated) >= @b2Date AND CONVERT(date,DateCreated) <@e2Date    
GROUP BY datepart(wk, DateCreated)
ORDER BY datepart(wk, DateCreated)

答案 3 :(得分:0)

是的,您可以使用相同的查询,但几乎没有修改。我使用了2个CTE,一个用于查询,另一个用于上一周。然后加入on weeknumber以获取所需的最后一列,如下所示。

BEGIN  
SET datefirst 1;  
DECLARE @BeginDate datetime= '2016-10-10'  

;WITH CTE1 as
  SELECT 
    count(*) as Total  
  , datepart(wk, DateCreated) as WeekNumber  
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104) as WeekStartDate  
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104) as WeekEndDate  
FROM TABLESES  
WHERE     
    CONVERT(date,DateCreated) >= DATEADD(DAY, -42, @BeginDate)   
    AND CONVERT(date,DateCreated) <= DATEADD(DAY, 6, @BeginDate)  
GROUP BY      datepart(wk, DateCreated)  
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,0),104)  
  , convert(VARCHAR(20),dateadd(week,datediff(day,0,DateCreated )/7,6),104)    

,CTE2 as  
SELECT count(*) as Total    
    ,datepart(wk, dateadd(year, -1, DateCreated)) as WeekNumber  
 FROM TABLESES    
GROUP BY datepart(wk, dateadd(year, -1, DateCreated))  

SELECT CTE1.*, CTE2.Total  
FROM CTE1 JOIN CTE2  
ON CTE1.WeekNumber  = CTE2.WeekNumber  

  END