用于确定非出席是否为“DROPOUT”的SQL

时间:2015-07-16 11:18:19

标签: sql sql-server time-and-attendance

我有一个出勤表,每周出席“出席”或“缺席”

并且需要按照以下原因进行更改:

如果一个人整整一个月都没有参加,那么他/她在那个月之前缺席的那几周就会被改为“DROPOUT”,直到他重新参加。

我已经尝试过使用SQL来检查“条纹”检查几个月的联合出席情况,但无法让“退出”是正确的。任何帮助将受到高度赞赏。

使用Sample SourceData,其中1为“Absent”& 0为“Present”,我使用了以下SQL但有一些错误

/* Calculate RunGroup */
SELECT WeekNum, Abs_Status, (SELECT COUNT(*) FROM [SourceData] G WHERE G.Abs_Status <> GR.Abs_Status AND G.WeekNum <= GR.WeekNum) as RunGroup 
INTO [RunGroup]
FROM [SourceData] GR;
GO

/* Determine how many weeks in each run */
SELECT Abs_Status, MIN(WeekNum) as StartDate, MAX(WeekNum) as EndDate, COUNT(*) as Games 
INTO [WeeksinRun]
FROM [RunGroup] A GROUP BY Abs_Status, RunGroup ORDER BY Min(WeekNum);
GO


/****** What to mark as Dropouts  ******/
SELECT [StartDate]
      ,[EndDate]
  INTO [WeekstoUpd]
  FROM [WeeksinRun] a,[SourceData] b, [SourceData] c
  where a.[StartDate] = b.[Weeknum]
  and a.[EndDate] = c.[Weeknum]
  and b.[MONTH] <> c.[MONTH]
  and a.Abs_Status = '1'
  and a.[StartDate] <> '2013 Week 01';
GO

/****** Update Dropout Weeks  ******/
update [SourceData]
set [SourceData].[Abs_Status] = '-2'
  FROM [SourceData],[WeekstoUpd]
  where [WeekNum]>=[StartDate] and [WeekNum]<=[EndDate];
GO

/****** Update Absent Weeks  ******/
UPDATE [SourceData]
SET    [Abs_Status] = '-1'
FROM   [SourceData]
WHERE  [SourceData].[Abs_Status] = '1';
GO

SQL Fiddle Code

1 个答案:

答案 0 :(得分:1)

不确定我是否理解这一点,但也许这就是你想要的:

update s 
set s.Abs_Status = 2
from SourceData S
where not exists (
  select 1 from SourceData S2
  where S2.Abs_Status = 0 and S2.MONTH = S.MONTH
) and Abs_status = 1

update s 
set s.Abs_Status = 2
from SourceData S
where 2 = (
  select top 1 S2.Abs_Status from SourceData S2
  where S2.Abs_Status <> 1 and S2.WeekNum > S.WeekNum
  order by S2.WeekNum asc
) and Abs_status = 1

update s 
set s.Abs_Status = 2
from SourceData S
where 2 = (
  select top 1 S2.Abs_Status from SourceData S2
  where S2.Abs_Status <> 1 and S2.WeekNum < S.WeekNum
  order by S2.WeekNum desc
) and Abs_status = 1

select * from [SourceData];

对于整月与Abs_Status = 1的行,第一次更新会将Abs_Status更新为2

接下来的2次更新会将缺席之前/之后的部分月份更新为2。

SQL Fiddle