2014-12-27 33 views
0

我正在开发一个教会的考勤监测数据库应用程序,其目标是获得每个成员的连续礼物和缺席。但连续计数将基于周sql - 获取连续的礼物和缺席

例如,我们每周有3个服务(星期一,星期三和星期五),但这些服务是相同的,(只是时间/日期不同)。所以成员可以参加任何这些会议的(他们可以参加所有的,如果他们想)

我必须找到连续的礼物和缺勤在一周的每个成员,例如 如果我在这个月出席2014 OD十二月是:

 S M T W T F S 
W1 - P - P - - - 
W2 - P - - - - - 
W3 - P - P - P - 
W4 - - - - - P - 
W5 - P - - - - - 

我有5个连续PRESENTS 我只能指望每周一名出席(其它任何派驻将被忽略)

这里是表

tbl_members

member_id last_name first_name ... and so on 
1   SANTIAGO JOHN KERNELLE 

tbl_service_attendances

att_index service_date member_id 
1   2014-12-01 1 
2   2014-12-03 1 
3   2014-12-08 1 
4   2014-12-15 1 
5   2014-12-17 1 
6   2014-12-19 1 
7   2014-12-26 1 
8   2014-12-29 1 

att_index是自动递增

,每参加一个成员,我用这个查询:

INSERT INTO tbl_service_attendances(service_date, member_id) VALUES('2014-12-29', 1) 

如果他们在出席8个服务一周,tbl_service_attendances每个会有8行(唯一的区别是b e他们的日期)。但它只会算作5连续礼物。 (每周一次计数)

S M T W T F S 
W1 - P - P - - - 
W2 - P - - - - - 
W3 - P - P - P - 
W4 - - - - - - - 
W5 - - - - - - - 

在这种情况下,我有2个连续的缺席,

我也知道,如果Consecutives是派驻或没啥

请帮助,在此先感谢

到目前为止,我已经通过循环查询完成了我的目标,但我认为,循环多次查询是不可取的

+0

请问哪个RDBMS(Sql Server,MySql,Oracle等) – StuartLC

+0

我用VB与mysql配合使用 – jks

+0

为什么你在乎谁出现? – Strawberry

回答

1

首先,这类问题我在支持窗口函数的DBMS中处理起来要容易得多,但这里有一个可以用于MySQL的想法。我们首先创建一个视图来简化事宜:

create view wa as select distinct member_id, week(service_date) as wk 
        from service_attendances; 

我假设我们正在处理一年的数据。如果不是年份必须包含在视图和下面的查询中。

这一观点在手,我们可以创建每周出勤的间隔为:

select member_id, min(start_wk), end_wk 
from (
    select wa1.member_id, wa1.wk as start_wk, min(wa2.wk) as end_wk 
    from wa as wa1 
    join wa as wa2 
     on wa1.member_id = wa2.member_id 
     and wa2.wk > wa1.wk 
     and not exists ( 
      select 1 
      from wa wa3 
      where wa2.member_id = wa3.member_id 
      and wa3.wk = wa2.wk + 1 
     ) 
    group by wa1.wk, wa1.member_id 
) as x 
group by member_id, end_wk; 

随着你的结果上面提供的数据是:

+-----------+---------------+--------+ 
| member_id | min(start_wk) | end_wk | 
+-----------+---------------+--------+ 
|   1 |   48 |  52 | 
+-----------+---------------+--------+ 

的间隙由此可以容易地导出。这本来是最容易创建此表达另一种观点,但MySQL的考虑这个作弊:

ERROR 1349 (HY000): View's SELECT contains a subquery in the FROM clause 

假设start_wk为1和end_wk是52年,你可以使用类似的技术,因为上面找到差距为每个成员。

希望它有帮助。

+0

谢谢,这真的有帮助 – jks

+0

不客气。如果您认为答案很有用,您可以投票支持并/或将其作为答案接受。科里安德解决方案也是如此。 – Lennart

1

一种解决方案是在此fiddle使用会话变量,如:

select IF (weekn = @prev + @n, 
      IF (@n := @n + 1, @prev, 1), 
      IF (@n:=0 OR @prev := weekn, weekn, 2)) start_sequence 
from (select distinct week(service_date) as weekn 
    from tbl_service_attendances 
    where member_id = 1 
    and year(service_date) = 2014 
    and month(service_date) = 12 
    order by weekn) as presences 
JOIN (SELECT @n := 0, @prev := week('2014-12-01')-2) AS setup; 

连续周由该序列的第一周数代替。从这里,你可以在这个查询上按“分组”,按start_sequence,“计数”一周的发生次数,并丢弃那些只发生一次的事件。

不退还尚未缺勤,但这可以通过

a)用查找表右接合部与你希望所有的周数来完成

B)使用负的周数来表示的周缺席

+0

感谢您的回答,我很感激 – jks