월별로 차트표출용 통계를 내야하는데 현재 있는 테이블로 어떤식으로 처리해야할지 1주일째 고민중입니다 ㅠㅠ..
A테이블
| GP_ID(PK) | GP_NM |
| 1 | 서울 |
| 2 | 인천 |
B테이블
| GA_ID(PK) | GP_ID(FK) | GA_NM |
| 1 | 1 | 강남 |
| 2 | 1 | 강북 |
| 3 | 1 | 논현 |
| 4 | 2 | 미추홀 |
C테이블
| SA_ID(PK) | GA_ID(FK) | SA_NM |
| 1 | 1 | 입구 |
| 2 | 1 | 출구 |
| 3 | 2 | 입구 |
| 4 | 3 | 입구 |
D테이블
| SP_ID(PK) | SA_ID(FK) | MEN | WOMEN | DATE |
| 1 | 1 | 15 | 25 | 2022-01 |
| 2 | 1 | 10 | 20 | 2022-01 |
| 3 | 2 | 30 | 45 | 2022-02 |
| 4 | 3 | 50 | 60 | 2022-04 |
| 5 | 4 | 25 | 30 | 2022-03 |
위의 테이블처럼 존재합니다.
이때 검색조건을 GP_ID = 1, DATE(날짜)를 2022-01 ~ 2022-04월까지 검색한다고 하면
(GP_ID는 필수선택, GA_ID는 선택하거나 전체검색, 날짜설정 필수)
| GA_ID | DATE | MEN | WOMEN |
| 1 | 2022-01 | 25 | 45 |
| 1 | 2022-02 | 30 | 45 |
| 1 | 2022-03 | 0 | 0 |
| 1 | 2022-04 | 0 | 0 |
| 2 | 2022-01 | 0 | 0 |
| 2 | 2022-02 | 0 | 0 |
| 2 | 2022-03 | 0 | 0 |
| 2 | 2022-04 | 50 | 60 |
| 3 | 2022-01 | 0 | 0 |
| 3 | 2022-02 | 0 | 0 |
| 3 | 2022-03 | 25 | 30 |
| 3 | 2022-04 | 0 | 0 |
위와 같은 형태로 결과가 표출되도록 작업을 하려고 합니다.
(MEN, WOMEN값은 동일한 GA_ID이면 합계로 표출이 되어야합니다)
선택한 날짜만큼 검색되려면 날짜데이터가 들어간 임시테이블이 필요하다고 해서 서브쿼리 형태로 출력시켜서 조인해봤는데
GA_ID가 제대로 표출이 안되서 막혔습니다.
도움을 받을 수 있을까요..
WITH Atbl (gp_id, gp_nm) AS ( SELECT 1, '서울' UNION ALL SELECT 2, '인천' ), Btbl (ga_id, gp_id, ga_nm) AS ( SELECT 1, 1, '강남' UNION ALL SELECT 2, 1, '강북' UNION ALL SELECT 3, 1, '논현' UNION ALL SELECT 4, 2, '미추홀' ), Ctbl (sa_id, ga_id, sa_nm) AS ( SELECT 1, 1, '입구' UNION ALL SELECT 2, 1, '출구' UNION ALL SELECT 3, 2, '입구' UNION ALL SELECT 4, 3, '입구' ), Dtbl (sp_id, sa_id, men, women, date) AS ( SELECT 1, 1, 15, 25, '2022-01' UNION ALL SELECT 2, 1, 10, 20, '2022-01' UNION ALL SELECT 3, 2, 30, 45, '2022-02' UNION ALL SELECT 4, 3, 50, 60, '2022-04' UNION ALL SELECT 5, 4, 25, 30, '2022-03' UNION ALL SELECT 6, 4, 27, 47, '2022-05' ) -- 결과에 Atbl 항목이 없어서 쿼리에서 Atbl 없어도 되긴하지만, 참고 쿼리라서 테이블을 다 포함은 시켰어요. SELECT Btbl.ga_id, Dtbl.date , SUM(CASE WHEN Dtbl.sa_id = Ctbl.sa_id THEN Dtbl.men ELSE 0 END) men , SUM(CASE WHEN Dtbl.sa_id = Ctbl.sa_id THEN Dtbl.women ELSE 0 END) women FROM Atbl INNER JOIN Btbl ON Atbl.gp_id = Btbl.gp_id INNER JOIN Ctbl ON Btbl.ga_id = Ctbl.ga_id CROSS JOIN Dtbl WHERE Atbl.gp_id = 1 AND Dtbl.date BETWEEN '2022-01' AND '2022-04' -- AND Btbl.ga_id = 2 GROUP BY Btbl.ga_id, Dtbl.date ORDER BY Btbl.ga_id, Dtbl.date
와,,, 대박
어떻게 이렇게 깔끔하게 쿼리문이 표출이 되는지.....
진짜 정말 감사합니다ㅠㅠㅠㅠ
크로스조인 이런거 전혀 몰랐는데 꼭 다시 공부해서 머리속에 집어넣겠습니다!
WITH Atbl (gp_id, gp_nm) AS
(
SELECT 1, '서울' UNION ALL
SELECT 2, '인천'
)
, Btbl (ga_id, gp_id, ga_nm) AS
(
SELECT 1, 1, '강남' UNION ALL
SELECT 2, 1, '강북' UNION ALL
SELECT 3, 1, '논현' UNION ALL
SELECT 4, 2, '미추홀'
)
, Ctbl (sa_id, ga_id, sa_nm) AS
(
SELECT 1, 1, '입구' UNION ALL
SELECT 2, 1, '출구' UNION ALL
SELECT 3, 2, '입구' UNION ALL
SELECT 4, 3, '입구'
)
, Dtbl (sp_id, sa_id, men, women, date) AS
(
SELECT 1, 1, 15, 25, '2022-01' UNION ALL
SELECT 2, 1, 10, 20, '2022-01' UNION ALL
SELECT 3, 2, 30, 45, '2022-02' UNION ALL
SELECT 4, 3, 50, 60, '2022-04' UNION ALL
SELECT 5, 4, 25, 30, '2022-03' UNION ALL
SELECT 6, 4, 27, 47, '2022-05'
)
SELECT a.gp_id
, a.gp_nm
, b.ga_id
, b.ga_nm
, e.ym
, IFNULL(SUM(d.men ), 0) men
, IFNULL(SUM(d.women), 0) women
FROM Atbl a
INNER JOIN Btbl b
ON a.gp_id = b.gp_id
CROSS JOIN
(WITH RECURSIVE ym AS
(
SELECT '2022-01' ym
UNION ALL
SELECT DATE_FORMAT(DATE_ADD(CONCAT(ym, '-01'), INTERVAL 1 MONTH), '%Y-%m') ym
FROM ym
WHERE ym < '2022-04'
)
SELECT *
FROM ym
) e
LEFT OUTER JOIN Ctbl c
ON b.ga_id = c.ga_id
LEFT OUTER JOIN Dtbl d
ON c.sa_id = d.sa_id
AND e.ym = d.date
WHERE a.gp_id = 1
GROUP BY a.gp_id
, a.gp_nm
, b.ga_id
, b.ga_nm
, e.ym
;