SQL 질문입니다 도와주세용 0 11 1,222

by 돼지뚱뙝이 [SQL Query] [2017.03.14 11:38:55]


테이블 이름 학적변동테이블

년도   학기   학번   변동학적      

2013    1       1        휴학

2013    2      1        휴학

2014    1       1        복학

2014    2     1        휴학

2015    1       1        휴학

2015    2       1        휴학

2016    1       1        복학

2016    2       1        휴학

 

일때 연속된 휴학의 카운터를 구하고싶습니다. 위 테이블의 1번학생이 2014 2학기에서 2015 2학기까지  연속된 휴학(3) 이 나와야 합니다 ㅠㅠ 

만약 연속된 휴학이 여러건이면 최종거의 횟수가 나왔으면 합니다. 휴학은 한학기마다 자동으로 연장됩니다.

학교 학적변동프로젝트를진행하는대 어렵내요 ㅠㅠ

by 서승표 [2017.03.14 12:51:32]

음.. 저도 sql은 초보라.. 어거지로라도 짜보겟습니다;

SELECT 학번, COUNT(S)

FROM 학적변동

WHERE CONCAT(년도,학기) IN (20142, 20151, 20152)

AND 학번 = 1

AND 변동학적 = '휴학'

GROUP BY 학번;

 

이렇게하면 2014년도 2학기부터 2015년도 2학기까지 복학횟수가 나오지 안을까 싶내요

 

 


by 돼지뚱뙝이 [2017.03.14 13:44:39]

하드코딩은 지양하는지라 년도학기부분이 좀..


by jkson [2017.03.14 13:22:22]
with t as
(
select '2013' yyyy, '1' term, '1' id, '휴학' gb from dual union all
select '2013' yyyy, '2' term, '1' id, '휴학' gb from dual union all
select '2014' yyyy, '1' term, '1' id, '복학' gb from dual union all
select '2014' yyyy, '2' term, '1' id, '휴학' gb from dual union all
select '2015' yyyy, '1' term, '1' id, '휴학' gb from dual union all
select '2015' yyyy, '2' term, '1' id, '휴학' gb from dual union all
select '2016' yyyy, '1' term, '1' id, '복학' gb from dual union all
select '2016' yyyy, '2' term, '1' id, '휴학' gb from dual
)
select cnt cnt
  from
    (
    select max(yyyy) yyyy, count(1) + 1 cnt
    from
        (
        select yyyy,rnum,row_number() over(order by rnum) rnum2
          from
            (
            select yyyy, term, id, gb
                 , lag(gb) over(order by yyyy, term) befgb
                 , lag(yyyy) over(order by yyyy, term) befyyyy
                 , lag(term) over(order by yyyy, term) befterm
                 , row_number() over(order by yyyy, term) rnum
              from t
             where id = :id
            )
         where gb = befgb
           and gb = '휴학'
           and (yyyy = befyyyy or (term != befterm and yyyy - 1 = befyyyy)) 
        )
    group by rnum - rnum2
    having count(1) + 1 > 1
    order by yyyy desc
    )
  where rownum = 1

뭔가 복잡하네요. 간단하게 할 수있을 것 같은데..


by 돼지뚱뙝이 [2017.03.14 13:44:21]

감사합니다 jkson님


by 마농 [2017.03.14 13:29:51]
WITH t AS
(
SELECT 1 no, '2013' yyyy, 1 seq, '휴학' gb FROM dual
UNION ALL SELECT 1, '2013', 2, '휴학' FROM dual
UNION ALL SELECT 1, '2014', 1, '복학' FROM dual
UNION ALL SELECT 1, '2014', 2, '휴학' FROM dual
UNION ALL SELECT 1, '2015', 1, '휴학' FROM dual
UNION ALL SELECT 1, '2015', 2, '휴학' FROM dual
UNION ALL SELECT 1, '2016', 1, '복학' FROM dual
UNION ALL SELECT 1, '2016', 2, '휴학' FROM dual
)
SELECT no
     , cnt
  FROM (SELECT no
             , COUNT(*) cnt
             , ROW_NUMBER() OVER(PARTITION BY no ORDER BY MIN(yyyy || seq) DESC) rn
          FROM (SELECT no, yyyy, seq, gb
                     , ROW_NUMBER() OVER(PARTITION BY no     ORDER BY yyyy, seq) rn1
                     , ROW_NUMBER() OVER(PARTITION BY no, gb ORDER BY yyyy, seq) rn2
                  FROM t
                )
         WHERE gb = '휴학'
         GROUP BY no, rn1-rn2
        HAVING COUNT(*) > 1
        )
 WHERE rn = 1
;

 


by 돼지뚱뙝이 [2017.03.14 13:42:24]

마농님 정말감사합니다. 어떤방법으로 해결해야할지 감도못잡고있었는대 정말 감사합니다. 알려주신방법을 풀어서 잘해결하겠습니다.  이해하는대도 시간이 좀걸릴거같내요 ㅎㅎ


by jkson [2017.03.14 13:43:48]

아! 복학을 기준으로 그룹지으면 간단하네요. 역시 乃


by 돼지뚱뙝이 [2017.03.14 13:42:48]

답변주신 서승표, jkson , 마농님 정말감사합니다. 


by 마농 [2017.03.14 14:01:29]
SELECT no
     , LENGTH(
       REGEXP_SUBSTR(
       LISTAGG(gb) WITHIN GROUP(ORDER BY yyyy DESC, seq DESC)
       , '(휴학){2,}')
       ) / 2 cnt
  FROM t
 GROUP BY no
;

 


by 돼지뚱뙝이 [2017.03.14 14:09:31]

정규식의 활용도가 무긍무진하군요.. 위에 올려주신것도 한30분정도 분석해서 겨우 감을잡았는대 이번에 올려주신걸 잘 공부하면 활용도가 여러방도일거같군여


by jkson [2017.03.14 14:28:43]

헐...... 헐... 헐. 어렵겠지만 저에게도 이런 생각을 할 수 있는 날이 오길..

댓글등록
SQL문을 포맷에 맞게(깔끔하게) 등록하려면 code() 버튼을 클릭하여 작성 하시면 됩니다.
로그인 사용자만 댓글을 작성 할 수 있습니다. 로그인, 회원가입