SET DATEFIRST
将一周的第一天设置为从 1 到 7 之间的一个数字。语法
SET DATEFIRST { number | @number_var } 参数
number | @number_var是一个整数,表示一周的第一天,可以是下列值中的一个

解决方案 »

  1.   

    set datefirst 1
    select ...
      

  2.   

    可以使用@@datefirst 函数检查 set datefirst 的当前设置。
      

  3.   

    SET DATEFIRST 好象对 datename 不起作用吧
      

  4.   

    set datefirst 对于这个问题无效,楼上可以去测试一下.
      

  5.   

    用datename(ww,时间参数+1)进行的group by就对了
      

  6.   

    to pbsql(风云) ,应该是-1,不是+1吧?datename(ww,时间参数-1)
      

  7.   

    谢谢楼上所有,
    请问这个属性是不是sqlserver的内置属性?
    如果更改了,是不是sqlserver所有的数据都会这样处理了呢???
    我想用一个select语句都搞定,可以吗???
      

  8.   

    to zjcxc(邹建):
    -1不能实现吧,
    我datename(ww,时间参数-1),并不能改变周的归属呀???
      

  9.   

    --测试:--2004-10-31 是星期日
    declare @dt datetime
    set @dt='2004-10-31'set datefirst 1
    select datename(ww,@dt)
    --结果: 45set datefirst 7
    select datename(ww,@dt)
    --结果: 45
    --说明  set datefirst 没有影响 datename(ww,@dt)select datename(ww,@dt-1)
    --结果: 44
    --说明结果是正确的了
      

  10.   

    如果你的时间参数是用字符型,则要用:datename(ww,dateadd(day,-1,时间参数))
    如果还是有问题,把你的测试写出来说明
      

  11.   

    建议不用 datename ,用 datepart
    datepart 受 set datefirst 影响
      

  12.   

    --2004-10-31 是星期日declare @dt datetime
    set @dt='2004-10-31'set datefirst 1
    select DATEPART(ww,@dt)
    --结果: 44set datefirst 7
    select DATEPART(ww,@dt)
    --结果: 45
    --说明  set datefirst 影响 DATEPART(ww,@dt)
      

  13.   

    各位,先拱手表示谢意~!
    实际情况是这样的,数据库里每天都会报一份数据上来,时间是当天(字段名是happentime),
    这样当我按周统计的时候,比如2004-2-1至2004-12-1,
    用datename(ww,时间参数)作为group by,
    可是即使按zjcxc(邹建)兄说的datename(ww,时间参数-1),也并不能让系统在这个时间段里
    把周日算到上一周里去呀,这样顶多是把时间向前提前一天而已,数据还是不正确的。
      

  14.   

    --比如2004-2-1至2004-12-1,应该是这样写的:select 周=datename(ww,happentime-1),统计=count(*)
    from 表 
    where happentime between '2004-2-1' and '2004-12-1'
    group by datename(ww,happentime-1)
      

  15.   

    datename(week,happentime-1) 
    有跨年数据 2004-1-1 至 2005-1-1 是有问题的!2005-1-1 的数据会算在 2004-1-1 的数据汇总里!另外, 1995-01-01 是一个周日 他与 1995-01-02 应算跨两周,应占两个周次!
    然而 select dataname(ww,'1995-01-01'),dataname(ww,'1995-01-02') 都是 1 !!!
    而且 select datename(ww,dateadd(day,-1,'1995-01-01'))
    返回的是 53 !显然不对!
    这种周次的处理(周日算作上周)参阅我的 blog:
    http://blog.csdn.net/playyuer/archive/2004/04/07/2860.aspx--set datefirst 3
    --set datefirst 4select max(happentime),min(happentime)
    --,happentime
    --,datename(weekday,happentime)
    ,datediff(week
                     ,case when (@@datefirst + datepart(weekday,dateadd(day,0,datediff(day,0,dateadd(year,datediff(year,0,happentime),0))))) % 7 = 1
                                then dateadd(day,-1,dateadd(day,0,datediff(day,0,dateadd(year,datediff(year,0,happentime),0))))
                           else dateadd(day,0,datediff(day,0,dateadd(year,datediff(year,0,happentime),0))) --date 所在年的第一天 即: 一月一号
                      end
                     ,case when (@@datefirst + datepart(weekday,happentime)) % 7 = 1
                                then dateadd(day,-1,happentime)
                           else happentime
                      end
                    ) + 1 as WeekOfYear
    ,datediff(week,0,case when (@@datefirst + datepart(weekday,happentime)) % 7 = 1
                                then dateadd(day,-1,happentime)
                           else happentime
                      end) 
    --,datediff(week,0,happentime)
    ,count(*) --这里换成你的聚集函数
    from d
    where happentime between '1995-03-02' and '1995-04-02'
    group by 
             datediff(week,0,case when (@@datefirst + datepart(weekday,happentime)) % 7 = 1
                                then dateadd(day,-1,happentime)
                           else happentime
                      end) 
    ,datediff(week
                     ,case when (@@datefirst + datepart(weekday,dateadd(day,0,datediff(day,0,dateadd(year,datediff(year,0,happentime),0))))) % 7 = 1
                                then dateadd(day,-1,dateadd(day,0,datediff(day,0,dateadd(year,datediff(year,0,happentime),0))))
                           else dateadd(day,0,datediff(day,0,dateadd(year,datediff(year,0,happentime),0))) --date 所在年的第一天 即: 一月一号
                      end
                     ,case when (@@datefirst + datepart(weekday,happentime)) % 7 = 1
                                then dateadd(day,-1,happentime)
                           else happentime
                      end
                    ) + 1
    order by min(happentime)
      

  16.   

    呵呵,谢谢两位老大的指点,
    小弟不胜感激~~~~
    我从主管那里得到了一个解决办法,
    写了一个函数,
    把一周内的时间统一到了当周的周一,
    然后再group by,
    效果不错~~~
    两位的写的东西我会仔细研究的,
    再次感谢你们~!!!!!!!!!
      

  17.   

    create function udf_weekday(@ int,@date datetime)
    returns datetime
    as
    begin
    /*
    --周日算作(上一)周的最后一天 
      当 @ <= 1 代表将 @date 映射到 所在周的星期一
      当 @ = 2  代表将 @date 映射到 所在周的星期二
      当 @ = 3  代表将 @date 映射到 所在周的星期三
      当 @ = 4  代表将 @date 映射到 所在周的星期四
      当 @ = 5  代表将 @date 映射到 所在周的星期五
      当 @ = 6  代表将 @date 映射到 所在周的星期六
      当 @ >= 7 代表将 @date 映射到 所在周的星期日
      可用于按周汇总 Group by,均支持跨年跨月数据
    */return 
    (select --@date,datename(weekday,@date),(@@datefirst + datepart(weekday,@date)) % 7,3 - (@@datefirst + datepart(weekday,@date)) % 7,
               dateadd(day
                      ,case when (@@datefirst + datepart(weekday,@date)) % 7 = 0 --周六
                                  then 
                                       case when @ between 1 and 6
                                                 then @ - 6
                                            else 1
                                        end
                            when (@@datefirst + datepart(weekday,@date)) % 7 = 1 --周日(七)
                                  then
                                       case when @ between 1 and 6
                                                 then @ - 7
                                            else 0
                                        end                        when (@@datefirst + datepart(weekday,@date)) % 7 between 2 and 6 --周一至周五
                                  then 
                                       case when @ between 1 and 6
                                                 then  @ + 1 - (@@datefirst + datepart(weekday,@date)) % 7
                                            else 8 - (@@datefirst + datepart(weekday,@date)) % 7 
                                       end 
                        end
                      ,@date))
    /*
    测试:select date,datename(weekday,date),'映射到:',dbo.udf_weekday(2,date),datename(weekday,dbo.udf_weekday(1,date))
    from T
    order by date--===============
    set datefirst 4
    declare @ int,@a int
    set @ = 1
    select date,datename(weekday,date),(@@datefirst + datepart(weekday,date)) % 7,3 - (@@datefirst + datepart(weekday,date)) % 7,
               dateadd(day
                      ,case when (@@datefirst + datepart(weekday,date)) % 7 = 0 --周六
                                  then 
                                       case when @ between 2 and 7
                                                 then -(7-@)
                                            else @
                                        end
                            when (@@datefirst + datepart(weekday,date)) % 7 = 1 --周日
                                  then
                                       case when @ between 2 and 7
                                                 then -(7-@)-1
                                            else @ - 1
                                        end                        when (@@datefirst + datepart(weekday,date)) % 7 between 2 and 6
                                  then 
                                       case when @ between 2 and 7
                                                 then  @ - (@@datefirst + datepart(weekday,date)) % 7
                                            else 8 - (@@datefirst + datepart(weekday,date)) % 7 
                                       end                                    
                        end
                      ,date)
    from d
    order by date
    */end