我在SQL Server工作,我有一个像这样的表;
我想要实现的目标;我正在整理一份病假最频繁的日子。我需要将[病假开始日期]列转换为一周中的某一天。使用DATENAME(day, GETDATE())
实现此目的没有问题。
这适用于获取用户第一次生病的星期几 - 但是[总天数]大于1时,我需要遍历每个日期并存储日期名称。
所以我希望实现类似下面的内容;
任何指针都将非常感谢!
答案 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)
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