2014-12-27 2 views
0

나는 각 회원에 대한 연속적인 선물 및 결석을 얻는 것이 목적 인 교회의 출석 모니터링 데이터베이스 응용 프로그램을 개발 중입니다. 연속 카운트는 주 단위로 계산됩니다.sql - 연속 된 선물 및 결석을 얻으십시오

예를 들어 우리는 일주일에 3 번 (수요일에 하나, 수요일에 하나, 금요일에 하나) 서비스를 제공하지만 서비스는 동일합니다 (시간/날짜 만 다를 수 있습니다).). 회원은 모든 회의에 참석할 수 있습니다. (원하는 경우 모든 참석 가능)

2014 년 12 월에 내 출석 인 경우, 예를 들어 과 같이 각 회원마다 연속 선물과 결석을 찾아야합니다 (예 : ). 입니다 :

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

나는 단지 일주일에 한 출석을 (다른 현존 무시됩니다) 여기

테이블

입니다 계산해야한다 연속 5 PRESENTS 이

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

그들이 8 서비스에 참석하는 경우 : 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 모든 구성원의 참석을 위해 자동 증가

, 난이 쿼리를 사용 주, tbl_service_attendances는 각각 8 행을 갖습니다 (유일한 차이는 b 전자 그들의 날짜). 그러나 그것은 단지 5 개의 연속적인 PRESENTS로 간주됩니다. (주 당 하나의 카운트)이 경우

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

, 나는 사전

에서 연속 2 ABSENTS, 나는 또한 개의 연속은 현존가 있는지 모르거나

이 도움을 주시기 바랍니다 결석해야

, 감사를

지금까지 쿼리를 반복하여 내 목표를 완료했지만 여러 쿼리를 반복하는 것이 바람직하지 않은 것 같아요

+0

어느 RDBMS (SQL 서버, MySQL, 오라클 등) – 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; 

여기서는 1 년간의 데이터를 처리한다고 가정합니다. 아래의보기와 쿼리에 연도가 포함되어 있지 않은 경우 우리가 매주 출석 간격 만들 수 손이보기로

: 만약 결과 상기 제공된 데이터

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

갭이 쉽게로부터 유도 될 수있다 .

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

start_wk가 1이고 end_wk는 올해 52이며 격차를 찾기 위해 위와 유사한 기술을 사용할 수 있습니다 가정 : 그것은 쉬운이 표현의 또 다른 뷰를 생성하지만, MySQL이이 부정 행위를 고려했을 것이다 각 회원.

희망이 있습니다.

+0

thanks man, 정말 도움이됩니다. – jks

+0

당신을 진심으로 환영합니다. 답변이 유용하다고 생각되면 투표하거나 답변으로 수락 할 수 있습니다. Korianders 솔루션에서도 마찬가지입니다. – 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, "count"주 발생 횟수를 "그룹화"할 수 있으며 한 번만 발생하는 항목을 삭제할 수 있습니다.

그것은 아직 결석을 반환하지 않습니다, 그러나 이것은 바로 당신이 원하는 모든 주 번호를 조회 테이블과 결합

A) 수행 할 수있는 그 주 나타내는

B)를 사용하여 음의 주 번호 결석의

+0

답변 해 주셔서 감사합니다. 감사합니다. – jks