这是我的表/源数据,
|---------------------------------------------------|
|ID | DT | DAY | ATTENDANCE |
|-------+---------------+-----------+---------------|
|89 | 2014-08-23 | NULL | 1 |
|90 | 2014-08-24 | Sunday | NULL |
|91 | 2014-08-25 | NULL | 1 |
|92 | 2014-08-26 | NULL | 1 |
|93 | 2014-08-27 | NULL | 0 |
|94 | 2014-08-28 | NULL | 1 |
|95 | 2014-08-29 | NULL | 0 |
|96 | 2014-08-30 | NULL | 1 |
|97 | 2014-08-31 | Sunday | NULL |
|98 | 2014-08-01 | NULL | 1 |
|99 | 2014-08-02 | NULL | 1 |
|100 | 2014-08-03 | NULL | 0 |
|101 | 2014-08-04 | NULL | 0 |
|102 | 2014-08-05 | NULL | 1 |
|103 | 2014-08-06 | NULL | 1 |
|104 | 2014-08-07 | Sunday | NULL |
|105 | 2014-08-08 | NULL | 1 |
|106 | 2014-08-09 | NULL | 1 |
|107 | 2014-08-10 | NULL | 1 |
|---------------------------------------------------|
我想要给出一个结果。第5列[Streak]
是我想要计算的。它是根据出勤率计算的值。在任何一天,如果[ATTENDANCE] = 0
,[Streak]
重置为0。
|-------------------------------------------------------------|
|ID | DT | DAY | ATTENDANCE | Streak |
|-------+---------------+-----------+---------------+---------|
|89 | 2014-08-23 | NULL | 1 | 1 |
|90 | 2014-08-24 | Sunday | NULL | |
|91 | 2014-08-25 | NULL | 1 | 2 |
|92 | 2014-08-26 | NULL | 1 | 3 |
|93 | 2014-08-27 | NULL | 0 | 0 |
|94 | 2014-08-28 | NULL | 1 | 1 |
|95 | 2014-08-29 | NULL | 0 | 0 |
|96 | 2014-08-30 | NULL | 1 | 1 |
|97 | 2014-08-31 | Sunday | NULL | |
|98 | 2014-08-01 | NULL | 1 | 2 |
|99 | 2014-08-02 | NULL | 1 | 3 |
|100 | 2014-08-03 | NULL | 0 | 0 |
|101 | 2014-08-04 | NULL | 0 | 0 |
|102 | 2014-08-05 | NULL | 1 | 1 |
|103 | 2014-08-06 | NULL | 1 | 2 |
|104 | 2014-08-07 | Sunday | NULL | |
|105 | 2014-08-08 | NULL | 1 | 3 |
|106 | 2014-08-09 | NULL | 1 | 4 |
|107 | 2014-08-10 | NULL | 1 | 5 |
|-------------------------------------------------------------|
这是我到目前为止所做的。对我来说,星期日也会逐渐增加。 任何帮助,解决它..
SQL
SELECT X.*, X.ID - LU.FROMID + 1
FROM @TAB X LEFT JOIN
(
SELECT (SELECT MIN(ID) FROM @TAB) FROMID,MIN(ID) TOID FROM @TAB WHERE ATTENDANCE = 0
UNION
SELECT A.ID FROMID,B.ID TOID
FROM (SELECT ID,ROW_NUMBER() OVER (ORDER BY ID) R FROM @TAB WHERE ATTENDANCE = 0) A CROSS JOIN
(SELECT ID,ROW_NUMBER() OVER (ORDER BY ID) R FROM @TAB WHERE ATTENDANCE = 0) B
WHERE A.R = (B.R - 1)
UNION
SELECT MAX(ID),(SELECT MAX(ID) FROM @TAB) FROM @TAB WHERE ATTENDANCE = 0
UNION
SELECT MAX(ID),MAX(ID) + 1 FROM @TAB
) LU
ON X.ID >= LU.FROMID AND X.ID < LU.TOID
测试的来源数据:
SET DATEFORMAT DMY
DECLARE @TAB TABLE (ID INT IDENTITY(89,1),DT DATE,DAY VARCHAR(15),ATTENDANCE BIT)
INSERT INTO @TAB VALUES
('23-08-2014',Null,1),
('24-08-2014','Sunday',Null ),
('25-08-2014',Null ,1),
('26-08-2014',Null ,1),
('27-08-2014',Null ,0),
('28-08-2014',Null ,1),
('29-08-2014',Null ,0),
('30-08-2014',Null ,1),
('31-08-2014','Sunday',Null ),
('01-08-2014',Null ,1),
('02-08-2014',Null ,1),
('03-08-2014',Null ,0),
('04-08-2014',Null ,1),
('05-08-2014',Null ,0),
('06-08-2014',Null ,1),
('07-08-2014','Sunday',Null ),
('08-08-2014',Null ,1),
('09-08-2014',Null ,1),
('10-08-2014',Null ,1)
先谢谢。
答案 0 :(得分:1)
@HHH,我在@TAB周围添加了另一个临时表。这有效,请测试并告诉。
DECLARE @TAB2 TABLE (MASTERID INT IDENTITY(1,1),ID INT,DT DATE,DAY VARCHAR(15),ATTENDANCE BIT)
INSERT INTO @TAB2
SELECT * FROM @TAB WHERE DAY IS NULL
SELECT Y.*,
LU2.Streak
FROM @TAB Y LEFT JOIN (
SELECT X.ID, X.MASTERID - LU.FROMID + 1 [Streak]
FROM @TAB2 X LEFT JOIN
(
SELECT (SELECT MIN(MASTERID) FROM @TAB2) FROMID,MIN(MASTERID) TOID FROM @TAB2 WHERE ATTENDANCE = 0
UNION
SELECT A.MASTERID FROMID,B.MASTERID TOID
FROM (SELECT MASTERID,ROW_NUMBER() OVER (ORDER BY MASTERID) R FROM @TAB2 WHERE ATTENDANCE = 0) A CROSS JOIN
(SELECT MASTERID,ROW_NUMBER() OVER (ORDER BY MASTERID) R FROM @TAB2 WHERE ATTENDANCE = 0) B
WHERE A.R = (B.R - 1)
UNION
SELECT MAX(MASTERID),(SELECT MAX(MASTERID) FROM @TAB2) FROM @TAB2 WHERE ATTENDANCE = 0
UNION
SELECT MAX(MASTERID),MAX(MASTERID) + 1 FROM @TAB2
) LU
ON X.MASTERID >= LU.FROMID AND X.MASTERID < LU.TOID ) LU2
ON Y.ID = LU2.ID
结果:
答案 1 :(得分:1)
select
t.*,
t2.Seq,
(case ATTENDANCE
when 1 then ROW_NUMBER() over (partition by t2.Seq,t.attendance order by t.id)
when 0 then 0
else null end) Streak
from
@TAB t
outer apply
(select
count(1) as Seq
from
@tab t2
where
t2.id < t.ID
and
t2.ATTENDANCE = 0) as t2
order by
t.id
答案 2 :(得分:0)
您需要确定连续出勤日的组。您可以使用row_numbers()
方法的差异来执行此操作。从整体row_number()
(没有星期天)中减去row_number()
出勤率(并且没有星期天)。条纹的差异是恒定的。其余的只是另一个row_number()
电话。
这是它的样子:
select t.id, t.dt, t.day, t.attendance,
(case when t.day = 'Sunday' then NULL
else row_number() over (partition by attendance, grp order by dt)
end) as streak
from (select t.*,
(row_number() over (partition by day order by dt) -
row_number() over (partition by day, attendance order by dt)
) as grp
from @tab t
) t;
答案 3 :(得分:0)
根据您的要求,我认为这个查询会很有用,请更改字段名称和表名。这是一种在表格中计算简单运行总计的一种非常简单的方法......
SELECT a.id,a.dateday,a.dateval,(SELECT SUM(b.hoursday)FROM #temp b 其中b.dateday&lt; = a.dateday)为totalhours 来自#temp a
谢谢