쿼리 질문드립니다 0 6 1,321

by 보라돌이 [MySQL] SQL Query group by [2020.12.28 17:28:01]


안녕하세요. 밑 테이블에서 model을 기준으로 group by를 써서 합치려고 하는데요, 

number가 떨어졌을 때, 새롭게 합칠 수 있는 방법이 있을까요?

(number는 마지막 값을 출력합니다.)

model number
A1 1
A2 2
A3 3
A3 4
A3 1

 

원하는 결과입니다.

model

number

A1 1
A2

2

A3 4
A3 1

 

by 춘 [2020.12.28 20:08:30]

model 을 group by 하는데,

원하는 결과가 model A3 이 두개가 나와야 한다라...

 

number 가 떨어졌을 때, 새롭게 합칠 수 있는 방법이 뭘 의미하는지도 모르겠고...

(number 는 마지막 값을 출력합니다.)

그러면,

              model number

                A1       1

                A2       2

                A3       1

이런 결과를 원하는 것도 아니고...

A3 의 number 값이 4 와 1 두개가 나오는 조건도 이해가 안되고...

 

이걸 이해하고, 해석해서 쿼리를 짜주실분의 결과가 저도 궁금하네요...


by 보라돌이 [2020.12.28 23:33:49]

일단 답변 감사합니다,

질문을 이상하게 한 것 같네요.

model의 값이 A3일때, number는 3, 4, 1 입니다.

number는 계속 증가하는 숫자(3 -> 4)인데, 예외로 하향한 숫자(1)가 나왔을 때,

하향된 숫자 전(4)에서 끊어서 그룹화되고(하향된 숫자 전 값인 4 출력), 하향된 숫자(1)부터 다시 그룹화 되기를 원합니다.

꼭 group by를 사용하지 않아도 되지만, model을 기준으로 합칠 방법을 찾고 있습니다.

감사합니다


by 마농 [2020.12.29 08:54:06]

예시의 model 자체는 증가하는 방향인데.. A1 > A2 > A3
뒤죽박죽 섞이는 예가 나올 수도 있나요?
만약 다음과 같은 원본인 경우 결과가 어떻게 나와야 하나요?
[원본]
A1 1
A2 2
A2 1
A1 2
[결과]
???
A1 이 한줄로 나와야 하나요? 두줄로 나와야 하나요?
A1 이 한줄로 나와야 한다면? A2 보다 먼저 출력되어야 하나요? 나중에 출력이 되어야 하나요?

기타사항.
1. model 이나 number 와 같은 예약어를 컬럼명으로 사용하는 것은 좋지 않습니다.
- 컬럼명을 바꾸어 질문해 주시는게 좋습니다.
2. 이 문제는 정렬이 필요한 문제입니다.
- 정렬 기준항목을 추가로 제시해 주셔야 합니다.

WITH t AS
(
SELECT 1 s, 'A1' m, 1 n
UNION ALL SELECT 2, 'A2', 2
UNION ALL SELECT 3, 'A3', 3
UNION ALL SELECT 4, 'A3', 4
UNION ALL SELECT 5, 'A3', 1
)
SELECT m
     , MAX(n) n
  FROM (SELECT s, m, n
             , SUM(flag) OVER(PARTITION BY m ORDER BY s) grp
          FROM (SELECT s, m, n
                     , CASE WHEN LAG(n) OVER(PARTITION BY m ORDER BY s) < n THEN 0 ELSE 1 END flag
                  FROM t
                ) a
        ) a
 GROUP BY m, grp
;

 


by 보라돌이 [2020.12.29 09:53:03]

답변 감사합니다,

정렬 기준 항목을 추가한다면, 날짜 컬럼이 들어갈 것 같습니다.

제시 해주신 원본에 추가를 하자면

model number time
A1 1 2020-12-12
A2 2 2020-12-13
A2 1 2020-12-14
A1 2 2020-12-13

결과는

A1 2 2020-12-13
A2 2 2020-12-13
A2 1 2020-12-14

입니다.

A1이 한 줄로 나온 이유는, A1의 number가 증가 했기 때문이고(1 -> 2),

A2가 두 줄이 나온 이유는 A2의 number가 하락 했기 때문입니다(2 ->1). 

A2와 A1의 결과 출력 순서는 상관이 없습니다. 

order by 순서는  model -> time 순서 입니다.

number가 증가하면서 time도 증가합니다. 

가끔 예외로 number가 하락할 때가 있는데(time은 계속 증가), 이 때 number가 하락하기 전 마지막 값을 출력(A2 2),

하락 한 후 다시 증가한 값(A2 1)을 출력하고 싶습니다.

우려해주신 컬럼명은 실제 컬럼명이 아닌 예시입니다.

감사합니다.


by 마농 [2020.12.29 10:29:26]
WITH t AS
(
SELECT 'A1' m, 1 n, '2020-12-12' t
UNION ALL SELECT 'A2', 2, '2020-12-13'
UNION ALL SELECT 'A2', 1, '2020-12-14'
UNION ALL SELECT 'A1', 2, '2020-12-13'
)
SELECT m
     , MAX(n) n
     , MAX(t) t
  FROM (SELECT m, n, t
             , SUM(flag) OVER(PARTITION BY m ORDER BY t) grp
          FROM (SELECT m, n, t
                     , CASE WHEN LAG(n) OVER(PARTITION BY m ORDER BY t) < n THEN 0 ELSE 1 END flag
                  FROM t
                ) a
        ) a
 GROUP BY m, grp
;

 


by 보라돌이 [2020.12.29 11:01:28]

감사합니다! 많은 도움이 되었습니다.

좋은 하루 보내시길 바랍니다.

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