조인된 데이터 중 가장 최근 데이터가 출력되도록 하기 위해 1 1 4,288

by 정수리형 [MySQL] [2018.09.19 10:54:27]


A테이블 
cid 
name 
adress 

B테이블 
cpid 
cid 
tel 
email 

위같이 예를 들어 테이블 두개가 있습니다. 

게시판 리스트를 출력되는 항목은 

name adress tel email 입니다. 

여기서 B테이블에는 

Apk값이 여러개가 들어 갈수 잇습니다. 

ex) 
A테이블 
cid  name adress 
1    홍길동  A지역 

B테이블 
cpid  cid  tel  email 
  1      1  010  a@ 
  2      1  010  b@ 

들어가 있을경우 

이 쿼리문을 사용하여 화면에 출력하면 

select 1.name, 1.dress, 2,tel, 2.email from A as 1 left join B as 2 on 1.cid = 2.cid 

이렇게 했을 경우 

2개의 리스트가 출력이 됩니다. 

리스트에는 홍길동이라는 사람의 정보가 1개가 출력이 되도록 하여야 합니다. 

tel, email의 경우 cpid가 가장 최신인것 만 출력이 되어야 합니다. 

그래서 밑에와 같이 수정하여 테스트를 해보았는데 

select 1.name, 1.dress, 2.cpid,2,tel, 2.email from A as 1 left join B as 2 on 1.cid = 2.cid group by 1.cid 

1.cid로 그룹지은 후 데이터를 출력해보니 (B테이블의 cpid도 출력해보았습니다. 가장 최근 cpid값이 출력되는 확인차) 

cpid값이 가장 최근 값이 아닌 첫번째로 등록된 cpid =1 인 값이 출력이 됩니다. 

제가 원하는 형태라면 위의 B테이블에서 cpid =2 인값이 출력이 되어야 하느데 말이죠 

group 부분을 어떻게 묶어야 B테이블에서 cid 1인 값중에서 cpid값이 가장 최근 값을 가지고 올수 있을까요?

by 마농 [2018.09.19 13:07:20]
-- 1. 정렬 후 Group By --
-- 단, mySQL 에서만 허용되는 비표준 Group by 구문입니다.
SELECT *
  FROM (SELECT a.cid, a.name, a.address
             , b.cpid, b.tel, b.email
          FROM a
          LEFT OUTER JOIN b
            ON a.cid = b.cid
         ORDER BY a.cid, b.cpid DESC
        ) c
 GROUP BY cid
;
-- 2. 분석함수가 가능한 버전이라면?
SELECT *
  FROM (SELECT a.cid, a.name, a.address
             , b.cpid, b.tel, b.email
             , ROW_NUMBER() OVER(PARTITION BY a.cid ORDER BY b.cpid DESC) rn
          FROM a
          LEFT OUTER JOIN b
            ON a.cid = b.cid
        ) c
 WHERE rn = 1
;
-- 3. 서브쿼리 조건 활용
SELECT a.cid, a.name, a.address
     , b.cpid, b.tel, b.email
  FROM a
  LEFT OUTER JOIN b
    ON a.cid = b.cid
 WHERE NOT EXISTS (SELECT 1
                     FROM b c
                    WHERE c.cid  = b.cid
                      AND c.cpid > b.cpid
                   )
;
-- 3. 서브쿼리 조건 활용
SELECT a.cid, a.name, a.address
     , b.cpid, b.tel, b.email
  FROM a
  LEFT OUTER JOIN b
    ON a.cid = b.cid
 WHERE b.cpid = (SELECT MAX(c.cpid)
                   FROM b c
                  WHERE c.cid = b.cid
                 )
;
-- 4. 인라인뷰 활용
SELECT a.cid, a.name, a.address
     , b.cpid, b.tel, b.email
  FROM a
  LEFT OUTER JOIN
       (SELECT cid
             , MAX(cpid) cpid
          FROM b
         GROUP BY cid
        ) c
    ON a.cid = c.cid
  LEFT OUTER JOIN b
    ON c.cid  = b.cid
   AND c.cpid = b.cpid
;
-- 5. 셀프 아우터 조인 후 널 체크
SELECT a.cid, a.name, a.address
     , b.cpid, b.tel, b.email
  FROM a
  LEFT OUTER JOIN b
    ON a.cid = b.cid
  LEFT OUTER JOIN b c
    ON b.cid  = c.cid
   AND b.cpid < c.cpid
 WHERE c.cid IS NULL
;

 

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