SQL将日期转换为工作日名称

时间:2018-05-15 15:18:55

标签: sql sql-server date

我在SQL Server工作,我有一个像这样的表;

My Table

我想要实现的目标;我正在整理一份病假最频繁的日子。我需要将[病假开始日期]列转换为一周中的某一天。使用DATENAME(day, GETDATE())实现此目的没有问题。

这适用于获取用户第一次生病的星期几 - 但是[总天数]大于1时,我需要遍历每个日期并存储日期名称。

所以我希望实现类似下面的内容;​​

desired results

任何指针都将非常感谢!

5 个答案:

答案 0 :(得分:3)

首先生成您的疾病日期范围,然后加入日历表(我在这里递归生成一个)并按每天的名称分组。

;WITH RecursiveCalendar AS
(
    SELECT
        GeneratedDate = CONVERT(DATE, '2018-01-01')

    UNION ALL

    SELECT
        GeneratedDate = DATEADD(DAY, 1, C.GeneratedDate)
    FROM
        RecursiveCalendar AS C
    WHERE
        C.GeneratedDate < '2019-01-01'
),
SickRanges AS
(
    SELECT
        S.StartDate,
        EndDate = DATEADD(DAY, CEILING(S.DaysOff) - 1, S.StartDate)
    FROM
        YourTable AS S
)
SELECT
    Weekday = DATENAME(WEEKDAY, C.GeneratedDate),
    AmountSickDays = COUNT(1)
FROM
    SickRanges AS R
    INNER JOIN RecursiveCalendar AS C ON C.GeneratedDate BETWEEN R.StartDate AND R.EndDate
GROUP BY
    DATENAME(WEEKDAY, C.GeneratedDate)
ORDER BY
    COUNT(1) DESC
OPTION
    (MAXRECURSION 30000)

替换第二个CTE上的表和列以运行。

答案 1 :(得分:2)

enter image description here

IF OBJECT_ID('tempdb..#temp_DAYS_SICK') IS NOT NULL DROP TABLE #temp_DAYS_SICK
  CREATE TABLE #TEMP_DAYS_SICK
  (
  DAYWEEK VARCHAR(25)
  )
  DECLARE @DATE DATE,@TARGETDATE DATE,@OFFSET INT
  SET @OFFSET = 25
  SET @DATE = GETDATE()
  SET @TARGETDATE = DATEADD(DD,@OFFSET,@DATE)
  WHILE(@DATE <> @TARGETDATE)
  BEGIN
  INSERT INTO #TEMP_DAYS_SICK
  SELECT DATENAME(DW,@DATE)
  SET @DATE = DATEADD(DD,1,@DATE)
  END

  SELECT DAYWEEK,COUNT(1) AS DAYS_SICK FROM #TEMP_DAYS_SICK GROUP BY DAYWEEK

答案 2 :(得分:1)

我知道您正在尝试获取总休假天数大于1的那一天的名称。 试试这个......

select DATENAME(DW, DATEADD(day, TotalDaysOff, SickLeaveStartDate)) as SickDay 
from [table_name] where 
TotalDaysOff > 1

对马克来说,这可能就足够了:

select DATENAME(DW, DATEADD(day, TotalDaysOff, SickLeaveStartDate)) + ', ' + 
DATENAME(DW, DATEADD(day, (TotalDaysOff-1), SickLeaveStartDate)) as SickDay 
from [table_name] where 
TotalDaysOff > 1

但是,您可能希望对减量(TotalDaysOff-1)施加约束,以便它不会产生负值。因为这会影响结果并且可能无法按预期执行。

答案 3 :(得分:1)

根据我的理解,我试图进行这个查询,我希望他的作品和套装基于你想要的东西

SELECT T1.LEAVE_START_DAY, SUM(TOTAL_DAY_OFF) AS FREQUENCY
FROM
  (Select 
    DATENAME(DAY, START_DATE) AS LEAVE_START_DAY,
    TOTAL_DAY_OFF
  FROM TableLeave) T1
GROUP BY T1.LEAVE_START_DAY

答案 4 :(得分:1)

我把一些随机数据放到临时表中写这个:

select CAST(v.startDate as datetime) startDate, CAST(v.duration as int) duration
into ##leave
from (values('2018-05-15','9'),('2018-03-21','10'),('2018-01-12','5'),('2017-12-24','1'),('2017-11-25','10'),('2017-11-09','2'),('2017-09-28','2'),('2017-07-29','2'),('2017-05-18','1'),('2017-02-24','9'),('2016-11-28','4'),('2016-08-27','4'))v(startDate,duration)
;
declare @maxLeaveLen integer = (select MAX(duration) from ##leave)
;
with ml as (
    select 1 n
    union all
    select n + 1 from ml
    where n + 1 <= @maxLeaveLen
), sd as ( 
    select DATENAME(weekday, DATEADD(day, ml.n - 1, l.startDate)) [weekday]
    from ml ml
        cross join ##leave l
    where ml.n <= l.duration
) select sd.weekday, COUNT(1)
  from sd
  group by sd.weekday