卷起周末数据的方式与工作日不同

时间:2013-03-28 00:41:14

标签: sql sql-server sql-server-2008

我有这个问题:

SELECT 'Submission Date' = CAST(Submitted AS DATE)
    ,'DayOfWeek' = DATEPART(weekday, CAST(Submitted AS DATE))
    ,'DayOfWeekForm' = DATENAME(dw, CAST(Submitted AS DATE))
    ,'Submission Count' = count(*)
    ,'End Column' = CASE 
        WHEN (DATEPART(weekday, CAST(Submitted AS DATE))) IN (
                '1'
                ,'7'
                )
            THEN ('Weekend')
        ELSE DATENAME(dw, CAST(Submitted AS DATE))
        END
    ,'End Sub' = CASE 
        WHEN ('End Column' = 'Weekend')
            THEN NULL
        ELSE count(*)
        END
FROM dbo.xyz
WHERE CAST(Submitted AS DATE) BETWEEN '2012-09-01'
        AND '2012-09-10'
GROUP BY CAST(Submitted AS DATE)
ORDER BY CAST(Submitted AS DATE)

它返回:

Sub Date   DW  DayOfWeek   Sub Count  End Column  End Sub
---------  --  ----------  ---------  ----------  -------
 9/1/2012  7   Saturday    20         Weekend     20
 9/4/2012  3   Tuesday     126        Tuesday     126
 9/5/2012  4   Wednesday   141        Wednesday   141
 9/6/2012  5   Thursday    167        Thursday    167
 9/7/2012  6   Friday      132        Friday      132
 9/8/2012  7   Saturday    28         Weekend     28
 9/9/2012  1   Sunday      6          Weekend     6
9/10/2012  2   Monday      210        Monday      210

我的目标是将周末提交的内容添加到前一个星期五。即我希望09-01,09-08,09-09的End Sub字段显示为NULL。并为09-07显示166。

2 个答案:

答案 0 :(得分:1)

这样做:

SELECT CAST(Submitted AS DATE) AS [Submission Date]
    , DATEPART(weekday, CAST(Submitted AS DATE)) AS [DayOfWeek]
    , DATENAME(dw, CAST(Submitted AS DATE)) AS [DayOfWeekForm]
    , count(*) AS [Submission Count]
    , CASE 
        WHEN (DATEPART(weekday, CAST(Submitted AS DATE))) IN (
                '1'
                ,'7'
                )
            THEN ('Weekend')
        ELSE DATENAME(dw, CAST(Submitted AS DATE))
        END AS [End Column]
    , xyz_cnt._cnt AS [End Sub]
FROM dbo.xyz LEFT JOIN
 (SELECT CASE DATEPART(weekday, CAST(Submitted AS DATE))  
        WHEN '1' THEN DATEADD(dd, -2, CAST(Submitted AS DATE))
        WHEN '7' THEN DATEADD(dd, -1, CAST(Submitted AS DATE))
        ELSE CAST(Submitted AS DATE) END AS [SubmitDate]
    , count(*) AS _cnt 
  FROM dbo.xyz
  GROUP BY
  CASE DATEPART(weekday, CAST(Submitted AS DATE))  
        WHEN '1' THEN DATEADD(dd, -2, CAST(Submitted AS DATE))
        WHEN '7' THEN DATEADD(dd, -1, CAST(Submitted AS DATE))
        ELSE CAST(Submitted AS DATE) END ) AS xyz_cnt 
  ON CAST(xyz.Submitted AS DATE) = xyz_cnt.SubmitDate
WHERE CAST(Submitted AS DATE) BETWEEN '2012-09-01'
        AND '2012-09-10'
GROUP BY CAST(Submitted AS DATE), xyz_cnt._cnt
ORDER BY CAST(Submitted AS DATE)

答案 1 :(得分:1)

不确定我是否已经处理了所有可能的边缘情况,但这里似乎至少解决了一个直接的例子。

DECLARE @start DATE = '2012-09-01', @end DATE = '2012-09-10';

;WITH n(d,c,rn) AS 
(
  SELECT 
    CONVERT(DATE, Submitted), COUNT(*),
    ROW_NUMBER() OVER (ORDER BY CONVERT(DATE, Submitted))
  FROM dbo.xyz 
  WHERE Submitted >= @start AND Submitted < DATEADD(DAY, 1, @end)
  GROUP BY CONVERT(DATE, Submitted)
),
x(d,rn,c,dw,dn) AS 
(
  SELECT d,rn,c,DATEPART(WEEKDAY, d),DATENAME(WEEKDAY, d) FROM n
)
SELECT 
  [Sub Date] = x.d,
  [DayOfWeek] = x.dw,
  [DayOfWeekForm] = x.dn,
  [Sub Count] = x.c,
  [End Column] = CASE WHEN x.dw IN (1,7) THEN 'Weekend' ELSE x.dn END,
  [End Sub] = CASE 
    WHEN x.dw IN (1,7) THEN NULL 
    WHEN x.dw = 6 THEN x.c 
        + CASE WHEN x2.d = DATEADD(DAY, 1, x.d) THEN x2.c ELSE 0 END
        + CASE WHEN x3.d = DATEADD(DAY, 2, x.d) THEN x3.c ELSE 0 END
    ELSE x.c END 
FROM x
LEFT OUTER JOIN x AS x2 ON x.rn  = x2.rn-1 
LEFT OUTER JOIN x AS x3 ON x2.rn = x3.rn-1
ORDER BY x.d;

结果:

Sub Date    DayOfWeek  DayOfWeekForm  Sub Count  End Column  End Sub
----------  ---------  -------------  ---------  ----------  -------
2012-09-01  7          Saturday       20         Weekend     NULL
2012-09-04  3          Tuesday        126        Tuesday     126
2012-09-05  4          Wednesday      141        Wednesday   141
2012-09-06  5          Thursday       167        Thursday    167
2012-09-07  6          Friday         132        Friday      166
2012-09-08  7          Saturday       28         Weekend     NULL
2012-09-09  1          Sunday         6          Weekend     NULL
2012-09-10  2          Monday         210        Monday      210