join 질문이 있습니다 0 11 303

by zumsim [2020.05.21 10:20:08]


안녕하세요

다름이 아니고 join을 해서 데이터를 뽑으려는데 좀 막히고 헷갈려서요..

학습이력 테이블에서 학생별 과목 수강 횟수를 구하려는데

a 테이블( 이력) , b테이블(필요한 학생 id를 가져오는 쿼리) 를 조인해서 하려고 하는데

a,usrid(+) = b.usrid

이런식으로 하는게 아닐까 싶어서 해봐도 정상적으로 출력이 안되더라구요

b는 총 143건이 나오는데 저렇게 join 해서 조회하면 52개 밖에 안나와서 도움 요청드립니다.,

너무 정리안되게 주절거린거 같아 죄송합니다.

by 마농 [2020.05.21 10:59:47]
-- 1. 이너 조인 : 학습 한 학생만 나옴
SELECT a.usrid
     , a.usrnm
     , COUNT(*) cnt
  FROM 학생 a
     , 학습이력 b
 WHERE a.usrid = b.usrid
 GROUP BY a.usrid, a.usrnm
;
-- 2. 아우터 조인 : 학습 안한 학생도 나옴
SELECT a.usrid
     , a.usrnm
     , COUNT(b.usrid) cnt
  FROM 학생 a
     , 학습이력 b
 WHERE a.usrid = b.usrid(+)
 GROUP BY a.usrid, a.usrnm
;

 


by zumsim [2020.05.21 11:23:57]

저런 식으로 걸어줬는데도 학습안한 학생값은 나오질 않더라구요..

저기에 이력테이블이랑 조인되는 테이블이 1개 더있긴 한데 그것도 상관이 있을까요?


by 마농 [2020.05.21 11:27:13]

말로만 설명해서는 오류를 알 수 없죠.
작성된 쿼리를 보여주세요.
보안상 안된다면 비슷한 쿼리로라도 보여주세요.


by 버드나무 [2020.05.21 13:15:18]

where절아래 and조건에 a.use_yn = 'N' 이런식의 조건이 붙어 있는건 아녀요?


by zumsim [2020.05.21 13:24:31]

어 네 그런건가이네요ㅜ


by 마농 [2020.05.21 13:24:23]

1. 상수 조건 주의
 - a 에서 b 로 아우터 조인 걸 때
 - b 에 대한 상수조건에도 (+) 븉여 줘야 한다.
2. 연속 아우터 조인
 - a 에서 b 로 아우터 조인 걸 때
 - b 에 c 를 조인하려면 c 를 아우터 조인 해야 한다.
 - a > b > c 로 흘러 가는 형태로 순차적 아우터 조인
 

-- 3개 테이블 순차적 아우터 조인 예제
SELECT a.usrid
     , a.usrnm
     , COUNT(c.subj_no) cnt
  FROM 학생 a
     , 학습이력 b
     , 과목 c
 WHERE a.usrid = b.usrid(+)
   AND b.xxx(+) = 'Y'
   AND b.subj_no = c.subj_no(+)
   AND c.yyy(+) = 'N'
 GROUP BY a.usrid, a.usrnm
;

 


by zumsim [2020.05.21 13:27:01]

SELECT USRID, SUBJECT_NM, COUNT(*) FROM (
  SELECT A.USRID, A.FRDT, DECODE(SUBJECT_CD, '01', '국어', '02', '사회', '03', '수학', '04', '과학', '통합교과') AS SUBJECT_NM FROM TLMS_VIDEO_ROOM_USER A, TLMS_VIDEO_CLASS_SCHDL B, (                            
      SELECT MA.USRID
       FROM TCMN_USER_MASTER MA
      INNER JOIN TCMN_USER_DTL DTL
            ON MA.USRID = DTL.USRID
      INNER JOIN TCMN_USER_SCHAFS_DTL SCHA
            ON MA.USRID = SCHA.USRID
      INNER JOIN TCMN_SCHUL SCHL
          ON SCHA.SCHUL_ID = SCHL.SCHUL_ID
      INNER JOIN TCMN_OFCDC OFC
          ON SCHL.OFCDC_ID = OFC.OFCDC_ID
      LEFT OUTER JOIN (
        SELECT TU2.USRID
           , LISTAGG(MA.USR_NM, ',') WITHIN GROUP (ORDER BY MA.USR_NM) AS TUTOR_NM
          FROM TCMN_USER_SCHAFS_DTL_TUTOR TU2
            LEFT OUTER JOIN TCMN_USER_MASTER MA
         ON TU2.TUTOR_USRID = MA.USRID
         WHERE TU2.SCHAFS_MNG_ID IN (
           SELECT
                TSM.SCHAFS_MNG_ID
            FROM
                TLMS_SCHAFS_MNG TSM
            WHERE
                TSM.MNG_YEAR = '2020'    
           )
        GROUP BY TU2.USRID
      ) TU ON MA.USRID = TU.USRID
      LEFT OUTER JOIN
          (
              SELECT
                  TSMCU.USRID
                  , TSMC.TUTOR_USRID
              FROM
                  TLMS_SCHAFS_MNG_CLASS_USER TSMCU
              INNER JOIN
                  TLMS_SCHAFS_MNG_CLASS TSMC
              ON
                  TSMCU.SCHAFS_MNG_CLASS_ID = TSMC.SCHAFS_MNG_CLASS_ID
              INNER JOIN
                  TLMS_SCHAFS_MNG_GRADE TSMG
              ON
                  TSMC.SCHAFS_MNG_GRADE_ID = TSMG.SCHAFS_MNG_GRADE_ID
              WHERE
                  TSMG.SCHAFS_MNG_ID IN (
                      SELECT
                          TSM.SCHAFS_MNG_ID
                      FROM
                          TLMS_SCHAFS_MNG TSM
                      WHERE
                  TSM.MNG_YEAR = '2020'    
                  )
          ) OTU
          ON
              MA.USRID = OTU.USRID
      WHERE MA.DEL_YN = 'N'
       AND SCHA.SCHAFS_MNG_ID IN (
           SELECT
                TSM.SCHAFS_MNG_ID
            FROM
                TLMS_SCHAFS_MNG TSM
            WHERE
                TSM.MNG_YEAR = '2020'    
           )    
       
        AND OFC.OFCDC_ID != 187 
        AND SCHA.STUDENT_STCD != '2' ) C
  WHERE A.USRID(+) = C.USRID
    AND A.VIDEO_CLASS_SCHDL_ID = B.VIDEO_CLASS_SCHDL_ID
    AND SUBJECT_CD = '01'
)
GROUP BY USRID, SUBJECT_NM
ORDER BY USRID
;

 

좀 정신없긴한데 쿼리 그대로 보여드릴게요 

C로 묶인 부분이 제가 알고싶은 학생들의 USRID가 출력되는 거고 이걸 가지고 A,B와 묶어서 정보를 뽑아내려고 하고있습니다.


by 마농 [2020.05.21 14:31:00]

제가 바로 위에 답변 달았던 "3개 테이블 순차적 아우터 조인" 부분 읽고 이해하도록 헤보세요.
subject_cd 는 어떤 테이블의 컬럼일까요? a? b?
앞에 테이블 알리아스를 붙여주세요.

-- 수정전 --
 WHERE a.usrid(+) = c.usrid
   AND a.video_class_schdl_id = b.video_class_schdl_id
   AND subject_cd = '01'
-- 수정후 --
 WHERE a.usrid(+) = c.usrid
   AND a.video_class_schdl_id = b.video_class_schdl_id(+)
   AND b.subject_cd(+) = '01'

 


by zumsim [2020.05.21 14:51:21]

SUBJECT_CD 는 B의 컬럼이고 

우선 A가 학생이 화상수업에 입장한 이력이고 그 방 코드를 통해 B에서 어떤 과목의 화상수업이었는지를 가져오는거구

C의 USRID를 A와 조인해서 학생이 어떤 화상수업을 몇번 들었는지를 구하고 싶은거에요ㅠ..

우선 말씀대로 위에 답변달린 부분 부터 읽고 이해해보겠습니다!


by 마농 [2020.05.21 14:55:43]

A 가 기준이라면 아우터 조인을 거꾸로 하신 거죠.

SELECT a.usrid
     , DECODE(b.subject_cd, '01', '국어'
                          , '02', '사회'
                          , '03', '수학'
                          , '04', '과학'
                                , '통합교과') AS subject_nm
     , COUNT(c.usrid) cnt
  FROM tlms_video_room_user a
     , tlms_video_class_schdl b
     , (SELECT ma.usrid
         -- ...
        ) c
 WHERE a.usrid = c.usrid(+)
   AND a.video_class_schdl_id = b.video_class_schdl_id
   AND b.subject_cd = '01'
 GROUP BY a.usrid, b.subject_cd
 ORDER BY a.usrid, b.subject_cd
;

 


by 마농 [2020.05.21 14:35:20]

그리고 C 가 기준인가요? a 가 기준인가요?
기준이 뭔가요? c = a(+) 했으면 C 가 기준인데 Group By 는 c 가 아닌 a 로 하고 있고?

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