2014-09-04 122 views
2

这是我的表/源数据,计算在SQL Server中运行计数排除某些行

|---------------------------------------------------| 
|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

是否有意盟友的日期从2014-08-31到2014-08-01? – 2014-09-04 12:17:04

+0

@GordonLinoff,这是一个错误,日期是8月之后的9月份。我将编辑它... – HHH 2014-09-04 12:19:10

回答

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 

结果:

enter image description here

+0

我不能避免像“谢谢”的评论.. Thanku Thanku Thanku .. – HHH 2014-09-04 12:36:30

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; 
+0

我在你的SQL中添加了一个“order by t.id”并执行。我会 – HHH 2014-09-04 12:23:46

1

像戈登说,你需要确定连续attendace一天的团体。但是,这是另外一个版本..

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 
0

根据您的要求,我觉得这个查询将是有用的,请改变字段名和表name.it是一个非常简单的方式来获得一个表中简单的计算运行总和。 .....

SELECT a.id,a.dateday,a.dateval,(SELECT SUM(b.hoursday)FROM #TEMP b WHERE b.dateday < = a.dateday)作为totalhours FROM# temp a

谢谢

相关问题