숫자문자열 정렬 질문드립니다 1 20 2,593

by 그냥토끼 [SQL Query] [2023.01.25 16:45:09]


1.PNG (4,931Bytes)
3.PNG (3,945Bytes)

데이터 타입이 문자형인데 숫자열 순으로 정렬하고 싶은데 모르겠어서 질문드립니다.

출력하고 싶은 결과는 2020-1 , 2020-2 순으로 월별 순서대로 정렬하고 싶습니다.

현재 쿼리는

 select convert(nvarchar(10), year(ssh.so_dt)) + '-' + convert(nvarchar(10), month(ssh.so_dt)) as '년월별',
        sum(ssd.so_qty) as 전체수량,
        sum(ssd.net_amt_loc) as 총금액
      from s_so_hdr as ssh
         inner join s_so_dtl as ssd on ssh.so_no = ssd.so_no
      where ssh.so_dt between '2020-01-01' and '2020-12-31'
      group by convert(nvarchar(10), year(ssh.so_dt)) + '-' + convert(nvarchar(10), month(ssh.so_dt))
      order by convert(nvarchar(10), year(ssh.so_dt)) + '-' + convert(nvarchar(10), month(ssh.so_dt))

이렇게 되어있습니다.

 

추가로 2020년도 1월~12월의 수량이랑 금액 합계를 맨 마지막 12월 행 뒤에 추가로 출력 가능할까요?

by 마농 [2023.01.25 16:56:54]
-- 그룹 및 정렬 기준을 바꾸는 방안 --
SELECT CONVERT(NVARCHAR(10),  YEAR(ssh.so_dt)) + '-' +
       CONVERT(NVARCHAR(10), MONTH(ssh.so_dt)) AS "년월별"
     , SUM(ssd.so_qty) AS 전체수량
     , SUM(ssd.net_amt_loc) AS 총금액
  FROM s_so_hdr ssh
 INNER JOIN s_so_dtl ssd
    ON ssh.so_no = ssd.so_no
 WHERE ssh.so_dt BETWEEN '2020-01-01' AND '2020-12-31'
 GROUP BY YEAR(ssh.so_dt), MONTH(ssh.so_dt)
 ORDER BY YEAR(ssh.so_dt), MONTH(ssh.so_dt)
;

-- 년월별을 yyyy-mm 포멧으로 뽑는 방안 (2020-01, 2020-02) --
SELECT CONVERT(NVARCHAR(7), ssh.so_dt, 121) AS "년월별"
     , SUM(ssd.so_qty) AS 전체수량
     , SUM(ssd.net_amt_loc) AS 총금액
  FROM s_so_hdr ssh
 INNER JOIN s_so_dtl ssd
    ON ssh.so_no = ssd.so_no
 WHERE ssh.so_dt BETWEEN '2020-01-01' AND '2020-12-31'
 GROUP BY CONVERT(NVARCHAR(7), ssh.so_dt, 121)
 ORDER BY "년월별"
;

-- 참고로. 알리아스에 홑따옴표는 표준이 아님.
-- 변경전 : '년월별'
-- 변경후 : "년월별"

 


by 그냥토끼 [2023.01.25 17:06:33]

자세한 답변과 조언 감사합니다!

 

추가로 1~12월의 수량,금액 합계를 하나의 행과 열로 12월 다음 부분에 행으로 표시할려면 어떻게 해야할까요?


by 마농 [2023.01.25 17:10:54]
-- ROLLUP --
SELECT ISNULL(CONVERT(NVARCHAR(7), ssh.so_dt, 121), '합계') AS 년월별
     , SUM(ssd.so_qty) AS 전체수량
     , SUM(ssd.net_amt_loc) AS 총금액
  FROM s_so_hdr ssh
 INNER JOIN s_so_dtl ssd
    ON ssh.so_no = ssd.so_no
 WHERE ssh.so_dt BETWEEN '2020-01-01' AND '2020-12-31'
 GROUP BY ROLLUP(CONVERT(NVARCHAR(7), ssh.so_dt, 121))
 ORDER BY 년월별
;

 


by 그냥토끼 [2023.01.25 18:00:41]

감사합니다.

ROLLUP은(는) 인식할 수 없는 기본 제공 함수 이름이라고 실행 오류가 뜨긴 하는데 롤업 관련 찾아서 해보겠습니다

 


by 마농 [2023.01.25 18:15:25]
-- 버전이 어떻게 되나요?
-- 과거 버전이라면? WITH ROLLUP
 GROUP BY CONVERT(NVARCHAR(7), ssh.so_dt, 121) WITH ROLLUP

 


by 그냥토끼 [2023.01.25 18:24:12]

ssms 18쓰고 있습니다

 select convert(nvarchar(10), year(ssh.so_dt)) + '-' +
             convert(nvarchar(10), month(ssh.so_dt)) as 년월별,
        sum(ssd.so_qty) as 전체수량,
        sum(ssd.so_price) as 총금액
      from s_so_hdr as ssh
         inner join s_so_dtl as ssd on ssh.so_no = ssd.so_no
      where ssh.so_dt between '2020-01-01' and '2020-12-31'
      group by year(ssh.so_dt), month(ssh.so_dt)
      with rollup
      order by year(ssh.so_dt), month(ssh.so_dt)

 

이렇게 하니깐 

NULL 887038.000000 50500963247.77
NULL 887038.000000 50500963247.77
2020-1    
2020-2    
2020-3    
2020-4    
2020-5    
2020-6    
2020-7    
2020-8    
2020-9    
2020-10    
2020-11    
2020-12    

 

 

이런식으로 나오네요 빈칸에 데이터는 다 들어가 있는데 생략했습니다

 


by 마농 [2023.01.26 08:39:27]

SSMS 사용툴 버전 말고, MSSQL DB 버전 확인하셔야 할 듯.
제가 알려드린 롤업은 항목이 하나인데, 사용하신 롤업은 항목이 두개입니다.
새로운 버전의 ROLLUP 은 괄호를 사용해 해결이 가능한데요. ROLLUP((항목1, 항목2))
구 버전의 WITH ROLLUP 은 괄호 사용이 불가하여 쉽지 않습니다.
항목을 하나로 줄이셔야 할 듯 하네요.
2020-1 형식이어야만 하나요? 2020-01 형식이 보기 좋은데요?
제가 실수로 112 라고 적었는데 121 이네요. 답글 수정했습니다.


by 그냥토끼 [2023.01.26 10:12:50]

감사합니다! 말씀하신대로 형식도 저게 더 보기 좋은거 같아서 바꾸고 출력도 제대로 되네요!

버전은 Microsoft SQL Server 2005 - 9.00.5057.00 (X64)로 나옵니다.

 


by 그냥토끼 [2023.01.26 14:38:11]

혹시 select절 서브쿼리 그룹by정렬 관련해서 하나만 더 질문해도 될까요?

select isnull(convert(nvarchar(7), ssh.so_dt, 121), '총합계') as 년월별,
	   ssh.so_class as 산업분야,
	   so_class_nm = (select minor_nm from b_minor where major_cd = 'z' and minor_cd = ssh.so_class)
	   from s_so_hdr as ssh
  	   inner join s_so_dtl as ssd on ssh.so_no = ssd.so_no
	  where ssh.so_dt between '2020-01-01' and '2020-12-31' and ssh.so_class is not null
	  group by convert(nvarchar(7), ssh.so_dt, 121), ssh.so_class

 

이렇게 하니 ssh.so_class가 하나의 그룹으로 안묶여지네요..

select절의 서브쿼리가 아닌 다른 절의 서브쿼리를 해야할까요? 아니면 having같은거로 조건을 줘야 할까요?

여러가지 찾아보고 검색하다 해결 못해서 질문드려봅니다..

 


by 마농 [2023.01.26 15:13:18]
SELECT CONVERT(NVARCHAR(7), ssh.so_dt, 121) AS 년월별
     , ssh.so_class AS 산업분야
     , bm.minor_nm  AS so_class_nm
  FROM s_so_hdr ssh
 INNER JOIN s_so_dtl ssd
    ON ssh.so_no = ssd.so_no
  LEFT OUTER JOIN b_minor bm
    ON bm.major_cd = 'z'
   AND bm.minor_cd = ssh.so_class
 WHERE ssh.so_dt BETWEEN '2020-01-01' AND '2020-12-31'
   AND ssh.so_class IS NOT NULL
 GROUP BY CONVERT(NVARCHAR(7), ssh.so_dt, 121), ssh.so_class, bm.minor_nm
;

 


by 그냥토끼 [2023.01.26 17:26:38]

답변 감사합니다.

왜인지는 모르겠지만 그래도 그룹으로 안묶이네요

늦은 답글 죄송합니다


by 마농 [2023.01.26 17:29:22]

"그룹으로 안묶이네요" 가 무슨 뜻 인지 설명해 주세요.
결과표를 보여주시는게 이해하기 좋습니다.
현재쿼리 + 현재결과 vs 원하는 결과


by 그냥토끼 [2023.01.26 17:52:28]
년월별 산업분야 so_class_nm
2020-01 B 조선
2020-02 C 산업기계

이런식으로 2020년도의 월별(1월~12월),산업분야 별로(같은 산업분야끼리) 그룹으로 묶어서 나타내고 싶습니다


by 마농 [2023.01.26 18:01:21]

원하는 결과는 올려주셨는데...
이것만 봐서는 뭐가 문제인지 모르겠는데요.
현재 사용 쿼리와 현재 결과표도 올려주세요.


by 그냥토끼 [2023.01.26 18:18:53]
select isnull(convert(nvarchar(7), ssh.so_dt, 121), '총합계') as 년월별,
	   ssh.so_class as 산업분야,
	   so_class_nm = (select minor_nm from b_minor where major_cd = 'z' and minor_cd = ssh.so_class)
	   from s_so_hdr as ssh
  	   inner join s_so_dtl as ssd on ssh.so_no = ssd.so_no
	  where ssh.so_dt between '2020-01-01' and '2020-12-31' and ssh.so_class is not null
	  group by convert(nvarchar(7), ssh.so_dt, 121), ssh.so_class

 

현재 사용 쿼리입니다.

댓글에 이미지 첨부는 안되는걸로 보여서 본문에 사진 추가하겠습니다(본문 2번째 사진이 위 쿼리 실행결과입니다)


by 마농 [2023.01.26 18:24:48]

현재 결과표의 문제점이 뭔지 모르겠네요?
원하는 결과표가 2줄일리는 없어 보이고.
원하는 결과표를 현재 결과표 대비하여 정확하게 표현해 주세요.
그리고 단순 명칭만 조회하나요? 합계 같은 건 없나보네요?


by 그냥토끼 [2023.01.26 18:37:08]

수량이랑 금액 합계 조회는 있습니다.

select isnull(convert(nvarchar(7), ssh.so_dt, 121), '총합계') as 년월별,
 ssh.so_class as 산업분야,
 so_class_nm = (select minor_nm from b_minor where major_cd = 'zs009' and minor_cd = ssh.so_class)
       sum(ssd.so_qty) as 전체수량,
       sum(ssd.so_price) as 총금액
from s_so_hdr as ssh
 inner join s_so_dtl as ssd on ssh.so_no = ssd.so_no
where ssh.so_dt between '2020-01-01' and '2020-12-31' and ssh.so_class is not null
group by convert(nvarchar(7), ssh.so_dt, 121), ssh.so_class

위 쿼리로 산업분야별로 그룹을 지어 나타내고 싶습니다

 

년월별 전체수량 총금액 산업분야 so_class_num
2020-01 1 645 A 화공기
2020-02 2 654 B 산업기계
2020-03 3 56 C 조선
2020-04 4 654 D 발전
2020-05 5 56 E 프랜지
2020-06 6 876 F 해외오파
2020-07 7 564 G 풍력
2020-08 8 645 H 밸브
2020-09 9 6564 I 등등
2020-10 10 4 J 등등
2020-11 11 465656 K 등등
2020-12 12 54 L 등등
총합계 78 654 M 등등

위 표 처럼 나타내고 싶습니다

숫자나 명칭은 임의로 넣었습니다


by 그냥토끼 [2023.01.26 18:37:24]

설명이 부족해 죄송합니다


by 마농 [2023.01.26 20:49:55]

현재 결과가 맞고 원하는 결과는 터무니 없어 보입니다.
1월에 산업분야가 A 하나만 있지는 않을 것입니다.
그런데 1월에 A 만 보여진다고요?
2월에는 B 만 보여지고요?
원하는 결과는 말이 안되는 결과입니다.

원하는 결과가 이게 정말 맞다면?
좌측 3개 컬럼을 위한 쿼리와
우측 2개 컬럼을 위한 쿼리가 별개 아닌가요?
두 쿼리가 하나의 쿼리로 연결될 필요가 있을지 의문이네요.
 


by 그냥토끼 [2023.01.27 08:10:21]

생각해보니 말씀하신대로 그렇기도 하네요..

 

감사합니다 다시 생각 해볼게요

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