분류 전체보기

728x90

위의 테이블에서 USE_YYMM 컬럼을 가변될 기준으로 하여  

USE_TYPE 별로 합계 구하는 쿼리 예시.

 

-- 임시 테이블 생성
CREATE TABLE #MONEY_HISTORY(
	USE_TYPE		NVARCHAR(10)	NOT NULL,
	USE_YYMM	NVARCHAR(10)	NOT NULL,
	AMT			INT			NOT NULL
)

INSERT INTO #MONEY_HISTORY VALUES ('외식', '2022년 7월', 12000)
INSERT INTO #MONEY_HISTORY VALUES ('외식', '2022년 7월', 10000)
INSERT INTO #MONEY_HISTORY VALUES ('외식', '2022년 7월', 7000)
INSERT INTO #MONEY_HISTORY VALUES ('공과금', '2022년 7월', 30000)

INSERT INTO #MONEY_HISTORY VALUES ('외식', '2022년 8월', 11000)
INSERT INTO #MONEY_HISTORY VALUES ('생필품', '2022년 8월', 25000)
INSERT INTO #MONEY_HISTORY VALUES ('생필품', '2022년 8월', 50000)
INSERT INTO #MONEY_HISTORY VALUES ('공과금', '2022년 8월', 30000)

INSERT INTO #MONEY_HISTORY VALUES ('외식', '2022년 9월', 6000)
INSERT INTO #MONEY_HISTORY VALUES ('외식', '2022년 9월', 8000)
INSERT INTO #MONEY_HISTORY VALUES ('생필품', '2022년 9월', 10000)
INSERT INTO #MONEY_HISTORY VALUES ('공과금', '2022년 9월', 30000)

-- 가변될 기준 컬럼 ---------------------
SELECT DISTINCT USE_YYMM 
INTO #YYMM
FROM #MONEY_HISTORY

-- SQL 생성 -----------------------------                     
 DECLARE @SQL VARCHAR(MAX)                   
                        
 SELECT @SQL = 'SELECT USE_TYPE' 
 SELECT @SQL = @SQL + ', SUM(CASE WHEN USE_YYMM = ''' +  USE_YYMM  + '''' +                              
                      ' THEN AMT ELSE 0.00 END ) AS ''' + USE_YYMM +''''                                       
					  FROM #YYMM
 SELECT @SQL = @SQL + 
 'FROM #MONEY_HISTORY
 GROUP BY USE_TYPE
 ORDER BY USE_TYPE'

 EXEC (@SQL)  -- 가변 컬럼으로 조회
 
-- 임시 테이블 삭제 ---------------------
-- DROP TABLE #YYMM, #MONEY_HISTORY

 

실행 결과

 

728x90
728x90

1=1 (항상 참)을 활용하여 WHERE절의 조건문을 특정 조건(ex. 사용자입력)에 따라 다르게 수행되도록 해줄 수 있다.

 

예시로,

SELECT * FROM TEST
WHERE CODE IN ('A', 'B')

이런 쿼리가 있는데 사용자가 Y를 입력할 때만 CODE IN ('A', 'B') 조건문을 실행하고

Y가 아니거나 입력하지 않는다면 

SELECT * FROM TEST

이렇게 실행되도록 하고싶은 경우.

 

-- 임시테이블 생성
CREATE TABLE #TEST(
	CODE	NVARCHAR(1)	NOT NULL
)

INSERT INTO #TEST VALUES('A')
INSERT INTO #TEST VALUES('B')
INSERT INTO #TEST VALUES('C')
INSERT INTO #TEST VALUES('D')
INSERT INTO #TEST VALUES('E')

---------------------------------- 
-- 임시 사용자입력 변수 선언
DECLARE @USER_INPUT NVARCHAR(1)

-- Y를 입력한 경우
SET @USER_INPUT = 'Y'

SELECT * FROM #TEST
WHERE
((@USER_INPUT = 'Y' AND CODE IN ('A', 'B')) -- OR 앞쪽 조건이 실행됨
OR (@USER_INPUT <> 'Y' AND 1=1))


-- Y가 아닌 경우
SET @USER_INPUT = ''

SELECT * FROM #TEST
WHERE
((@USER_INPUT = 'Y' AND CODE IN ('A', 'B'))
OR (@USER_INPUT <> 'Y' AND 1=1)) -- OR 뒤쪽 조건이 실행됨
----------------------------------
-- DROP TABLE #TEST

 

결과

 

이런 식으로 응용할 수 있음

SELECT * FROM #TEST
WHERE
((@USER_INPUT = 'Y' AND CODE IN ('A', 'B')) 
OR (@USER_INPUT = 'N' AND CODE = 'C') 
OR (ISNULL(@USER_INPUT, '') = '' AND 1=1))

 

728x90
728x90

ISNULL(값, 값이 null 이면 대체할 값)

 

MS-SQL 에서 Empty 와 Null 은 구분됨

lSNULL(컬럼, '') = ''   로 비교해주면 Empty 와 Null 을 둘 다 체크할 수 있다.

컬럼이 Null 이면 Empty로 변경하고 Empty = Empty 인 것을 의미함

-- 임시테이블 생성
CREATE TABLE #TEST(
	SEQ		INT	NOT NULL,
	TEST		NVARCHAR(1) NULL
)

INSERT INTO #TEST VALUES('1', '')   -- Empty
INSERT INTO #TEST VALUES('2', NULL) -- Null

-- 전체 조회 ----------------------------------
SELECT * FROM #TEST

-- Empty 조회
SELECT * FROM #TEST WHERE TEST = ''

-- Null 조회
SELECT * FROM #TEST WHERE TEST IS NULL

-- Empty 또는 Null 조회
SELECT * FROM #TEST WHERE ISNULL(TEST, '') = ''

-----------------------------------------------
-- 임시테이블 삭제
-- DROP TABLE #TEST

 

결과

728x90
728x90

CURSOR : 테이블을 한 줄씩 읽어서 다른 작업을 진행할 때 사용

 

커서 구문

-- FOR SELECT문 -> 한 줄씩 읽을 타겟 데이터를 SELECT함
DECLARE 커서이름 CURSOR FOR
SELECT문

OPEN 커서이름
-- FETCH문 : 한 줄 읽음
FETCH NEXT FROM 커서이름 INTO @SELECT된컬럼들, ...

WHILE(@@FETCH_STATUS = 0)
	BEGIN
   		작업 진행(ex. SELECT, INSERT, UPDATE, DELETE, ... )

    		-- 다음 줄 읽음
    		FETCH NEXT FROM 커서이름 INTO @SELECT된컬럼들, ...
	END

CLOSE 커서이름
DEALLOCATE 커서이름

 

이중 커서 예시

예시로 이런 헤더, 디테일 테이블이 있다고 가정.

헤더 테이블의 PK는 CODE

디테일 테이블의 PK는 CODE, SEQ 로 헤더의 내역을 관리할 수 있음 → 헤더의 CODE = 디테일의 CODE 임

 

두 테이블을 모두 조회하도록 CURSOR  작성

-- 임시 테이블 생성
CREATE TABLE #HDR (
	CODE		NVARCHAR(1)	NOT NULL,	-- PK용
	FLAG			NVARCHAR(1)	NULL

CREATE TABLE #DTL (
	CODE		NVARCHAR(1)	NOT NULL,	-- PK용
	SEQ			INT			NOT NULL,	-- PK용
	CONTENT		NVARCHAR(20)	NULL
)

INSERT INTO #HDR VALUES('A', 'Y')
INSERT INTO #HDR VALUES('B', 'N')
INSERT INTO #DTL VALUES('A', 1, 'TEST')
INSERT INTO #DTL VALUES('A', 2, 'CONTENT')
INSERT INTO #DTL VALUES('A', 3, 'EXAMPLE')
INSERT INTO #DTL VALUES('B', 1, 'PRACTICE')
INSERT INTO #DTL VALUES('B', 2, 'SLEEPY')

-- 변수 선언 ----------------------------------------
DECLARE
	-- 커서로 읽을 SELECT문의 모든 컬럼을 선언
	@CODE		NVARCHAR(1),
	@FLAG		NVARCHAR(1),
	@SEQ		INT,
	@CONTENT	NVARCHAR(20),
	-- 결과 담을 변수
	@RESULT		NVARCHAR(100),
	@HDR_TEMP	NVARCHAR(50),
	@DTL_TEMP	NVARCHAR(50)
    
-- 헤더의 커서 --------------------------------------
-- FOR SELET문 -> 한 줄씩 읽을 타겟 데이터를 SELECT함
DECLARE HDR_CURSOR CURSOR FOR
SELECT CODE, FLAG FROM #HDR

SELECT @RESULT = ''

-- 헤더 반복시작
OPEN HDR_CURSOR
-- FETCH문 : 한 줄 읽음
FETCH NEXT FROM HDR_CURSOR INTO @CODE, @FLAG -- SELET문에서 조회한 컬럼들과 동일하게 맞춰야함
-- @@FETCH_STATUS = 0  : FETCH문 수행됨
-- @@FETCH_STATUS = -1 : FETCH문 수행 실패
-- @@FETCH_STATUS = -2 : FETCH문 수행됐으나 행 없음

WHILE (@@FETCH_STATUS = 0) -- 한 줄 읽는거 성공 시 WHILE 반복
	BEGIN
		-- 헤더에 대해 다른 작업 진행
		SELECT @HDR_TEMP = ''
		SELECT @HDR_TEMP = @CODE + '(' + @FLAG + ') { '
		 
		-- 디테일 커서 선언
		DECLARE DTL_CURSOR CURSOR FOR
		SELECT SEQ, CONTENT FROM #DTL 
        	WHERE CODE = @CODE -- 헤더의 PK로 조회함
		
        	-- 디테일 반복시작
		OPEN DTL_CURSOR
		SET @DTL_TEMP = ''
        
		FETCH NEXT FROM DTL_CURSOR INTO @SEQ, @CONTENT 
        
		WHILE (@@FETCH_STATUS = 0) 
			BEGIN
				-- 디테일에 대해 다른 작업 진행
            			SELECT @DTL_TEMP = @DTL_TEMP + @CODE + CAST(@SEQ AS VARCHAR) + '(' + @CONTENT + ') '

            			-- 디테일 다음 줄 읽음 
				FETCH NEXT FROM DTL_CURSOR INTO @SEQ, @CONTENT 
			END
        	-- 디테일 반복끝
		CLOSE DTL_CURSOR		-- 커서 닫기
		DEALLOCATE DTL_CURSOR	-- 커서 할당 해제

		SELECT @RESULT = @RESULT + @HDR_TEMP + @DTL_TEMP + '} '

		-- 헤더 다음 줄 읽음
        	FETCH NEXT FROM HDR_CURSOR INTO @CODE, @FLAG
	END

-- 헤더 반복끝
CLOSE HDR_CURSOR
DEALLOCATE HDR_CURSOR

-- 임시 테이블 삭제
DROP TABLE #HDR
DROP TABLE #DTL

-- 결과 ----------------------------------------------
SELECT '실행순서 : ' + @RESULT

 

실행결과

 

728x90
728x90

인원을 입력하고 점수를 입력하면 두 팀의 점수가 5:5에 근접하도록 팀을 배정해줍니다.

참고사항 : 결과 표를 클립보드에 복사할 수 있습니다. 인원을 재입력 하려면 reset을 클릭합니다. 모바일은 안 됩니다 ;-;

조건 : 짝수 인원만 가능, 최대 10명, 점수 필수입력







 

 
 

🔗 소스 https://github.com/nrmhvr/game_team 

 

GitHub - nrmhvr/game_team: 점수가 5:5 비율에 근접하도록 두 팀을 배정해주는 페이지

점수가 5:5 비율에 근접하도록 두 팀을 배정해주는 페이지. Contribute to nrmhvr/game_team development by creating an account on GitHub.

github.com

 

728x90