在选择中创建DateFirst

时间:2019-02-22 14:29:36

标签: sql dayofweek

我有一条Select语句,要求DateFirst = 1 Monday 在美国,默认值为7周日

如何修改它以将DateFirst嵌入到select语句中,以便可以将其创建为视图?

SET DATEFIRST 1;
SELECT
        T_APPLICANT.APPL_ID                                                  AS empID,
        T_APPLICANT.APPL_LASTNAME,
        T_APPLICANT.APPL_FIRSTNAME,
        T_APPLICANT_ASSIGNMENT.ASS_STARTDATE,
        DATEPART(ww, dbo.T_APPLICANT_ASSIGNMENT.ASS_STARTDATE)               AS WeekNo,
        DATEPART(WEEKDAY, dbo.T_APPLICANT_ASSIGNMENT.ASS_STARTDATE)          AS WeekDay,
        DATEPART(ww, GETDATE())                                              AS CurWeekNo,
        (T_APPLICANT_ASSIGNMENT.ASS_HOURS)                                   AS Total_Assigned_hrs,
        (T_APPLICANT_ASSIGNMENT.ASS_BILL)                                    AS AvgBill_Rate,
        (T_APPLICANT_ASSIGNMENT.ASS_PAY)                                     AS AvgPay_Rate,
        (T_APPLICANT_ASSIGNMENT.ASS_HOURS * T_APPLICANT_ASSIGNMENT.ASS_PAY)  AS Total_AmtPaid,
        (T_APPLICANT_ASSIGNMENT.ASS_HOURS * T_APPLICANT_ASSIGNMENT.ASS_BILL) AS Total_AmtBilled,
        (LTRIM(STR(DATEPART(yy, T_APPLICANT_ASSIGNMENT.ASS_STARTDATE))) + '-'
         + LTRIM(STR(DATEPART(M, T_APPLICANT_ASSIGNMENT.ASS_STARTDATE)))
        )                                                                    AS YearMo
FROM
        T_APPLICANT
    RIGHT OUTER JOIN
        T_APPLICANT_ASSIGNMENT
            ON T_APPLICANT.APPL_ID = T_APPLICANT_ASSIGNMENT.APPL_ID
WHERE
        DATEPART(ww, dbo.T_APPLICANT_ASSIGNMENT.ASS_STARTDATE)
        BETWEEN DATEPART(ww, GETDATE()) AND DATEPART(ww, GETDATE()) + 1
        AND DATEPART(yy, T_APPLICANT_ASSIGNMENT.ASS_STARTDATE) = DATEPART(yy, GETDATE())
        AND ASS_STATUS = 'A';

1 个答案:

答案 0 :(得分:0)

除非另有证明,否则无法在视图中设置DATEFIRST
而且两者都不在用户定义的函数中。

要使视图返回星期和星期几,就像DATEFIRST设置为1一样?
那可以使用不同的计算。

无论DATEFIRST设置如何,都还没有想出如何计算星期数,就像星期从星期一开始一样。
这是一个棘手的问题。
我知道,可以链接到带有星期几的Calendar表。
但这不是这里的目标。

但是,WEEKDAY也可以在不使用DATEPART的情况下进行计算。
例如,将CASEFORMAT组合在一起。
因为不管DATEFIRST设置如何,工作日的名称都保持不变。

ISO_WEEK也在星期一开始。
因此,可以在WHERE子句中使用它来过滤当前周和下周。

create table testdatefirst (
  id int primary key not null identity(1,1),
  dt date not null
)
GO
with rcte as
(
  select cast('2018-12-24' as date) dt
  union all
  select dateadd(day, 1, dt)
  from rcte
  where dt < cast('2019-03-01' as date)
)
insert into testdatefirst (dt)
select * 
from rcte 
order by dt
GO
68 rows affected
CREATE view vw_testdatefirst AS
select dt
, FORMAT(dt,'ddd','en-GB') as [dayname]
, DATEPART(WEEKDAY, dt) as [weekday]
, DATEPART(WEEK, dt) as [week]
-- , DATEPART(ISO_WEEK, dt) as [ISO_WEEK]
, case FORMAT(dt,'ddd','en-GB')
  when 'Mon' then 1 
  when 'Tue' then 2
  when 'Wed' then 3
  when 'Thu' then 4
  when 'Fri' then 5
  when 'Sat' then 6
  when 'Sun' then 7
  end as [weekday2]
, (((DATEPART(WEEKDAY, dt) + @@DATEFIRST-2)%7)+1) AS [weekday3]
from testdatefirst
where DATEPART(ISO_WEEK, dt) between DATEPART(ISO_WEEK, '2019-01-01') and DATEPART(ISO_WEEK, '2019-01-01')+1
GO
set datefirst 7;
GO
select @@datefirst as [datefirst];
select * from vw_testdatefirst order by dt;
GO
| datefirst |
| :-------- |
| 7         |

dt                  | dayname | weekday | week | weekday2 | weekday3
:------------------ | :------ | ------: | ---: | -------: | -------:
31/12/2018 00:00:00 | Mon     |       2 |   53 |        1 |        1
01/01/2019 00:00:00 | Tue     |       3 |    1 |        2 |        2
02/01/2019 00:00:00 | Wed     |       4 |    1 |        3 |        3
03/01/2019 00:00:00 | Thu     |       5 |    1 |        4 |        4
04/01/2019 00:00:00 | Fri     |       6 |    1 |        5 |        5
05/01/2019 00:00:00 | Sat     |       7 |    1 |        6 |        6
06/01/2019 00:00:00 | Sun     |       1 |    2 |        7 |        7
07/01/2019 00:00:00 | Mon     |       2 |    2 |        1 |        1
08/01/2019 00:00:00 | Tue     |       3 |    2 |        2 |        2
09/01/2019 00:00:00 | Wed     |       4 |    2 |        3 |        3
10/01/2019 00:00:00 | Thu     |       5 |    2 |        4 |        4
11/01/2019 00:00:00 | Fri     |       6 |    2 |        5 |        5
12/01/2019 00:00:00 | Sat     |       7 |    2 |        6 |        6
13/01/2019 00:00:00 | Sun     |       1 |    3 |        7 |        7
set datefirst 1;
GO
select @@datefirst as [datefirst];
select * from vw_testdatefirst order by dt;
GO
| datefirst |
| :-------- |
| 1         |

dt                  | dayname | weekday | week | weekday2 | weekday3
:------------------ | :------ | ------: | ---: | -------: | -------:
31/12/2018 00:00:00 | Mon     |       1 |   53 |        1 |        1
01/01/2019 00:00:00 | Tue     |       2 |    1 |        2 |        2
02/01/2019 00:00:00 | Wed     |       3 |    1 |        3 |        3
03/01/2019 00:00:00 | Thu     |       4 |    1 |        4 |        4
04/01/2019 00:00:00 | Fri     |       5 |    1 |        5 |        5
05/01/2019 00:00:00 | Sat     |       6 |    1 |        6 |        6
06/01/2019 00:00:00 | Sun     |       7 |    1 |        7 |        7
07/01/2019 00:00:00 | Mon     |       1 |    2 |        1 |        1
08/01/2019 00:00:00 | Tue     |       2 |    2 |        2 |        2
09/01/2019 00:00:00 | Wed     |       3 |    2 |        3 |        3
10/01/2019 00:00:00 | Thu     |       4 |    2 |        4 |        4
11/01/2019 00:00:00 | Fri     |       5 |    2 |        5 |        5
12/01/2019 00:00:00 | Sat     |       6 |    2 |        6 |        6
13/01/2019 00:00:00 | Sun     |       7 |    2 |        7 |        7

db <>提琴here