[Database] UNION

h220101·2022년 8월 2일
0
post-custom-banner

유니온 UNION

여러개의 쿼리의 합집합이다.
여러개의 SQL문을 합쳐서 하나의 SQL문으로 만들어주는 방법
📢 SELECT 개수가 동일해야 한다.

UNION VS UNION ALL

  • UNION : 여러개의 쿼리의 중복값을 제거한 결과
  • UNION ALL : 여러개의 쿼리결과가 중복이 되더라도 전부 결과에 반영
  • 속도 : UNION ALL > UNION

규칙

  • 각 SELECT의 컬럼의 수가 같아야 한다.
  • 컬럼명이 같아야 한다.
    ( 같지 않을 경우 alias를 사용하여 같게 만듦)
  • 컬럼별 데이터타입이 같아야 한다. ( 반환 가능한 형태 )
  • 하나의 ORDER BY만 사용한다.
  • SELECT문들의 순서는 상관없다.

UNION

UNION ALL



DML (1) - 1부터 시작하는 행의 번호를 포함하여 상품테이블을 출력하시오.

SELECT
	@rowNum:=(@rowNum+1) AS '행 번호'
	,g.*
FROM
	tb_goods AS g
	,(SELECT @rowNum:=0) r
	
ORDER BY	g.g_price DESC;

DML (2) - 상품테이블의 단가 중 단가가 높은 상품 순서대로 순위를 포함하여 상품테이블을 출력하시오.

SELECT
	CASE
	WHEN (@gPri := g.g_price) THEN @rank:=(@rank+1)
	WHEN (@gPri = g.g_price) THEN @rank
	END AS '순위'
	,g.*
FROM
	tb_goods AS g
	,(SELECT @rank:=0, @gPri:=null) r
	
ORDER BY	g.g_price DESC;

DML (3) - 관리자 제외한 회원 별 로그인 평균 횟수보다 많이 로그인한 회원 아이디와 로그인 횟수를 조회 하시오.

SELECT
	l.login_id AS '아이디'
	,COUNT(l.login_id) AS '로그인횟수'
FROM
	tb_login AS l
	INNER JOIN 
	tb_member AS m
	ON 
	m.m_id =  l.login_id
	INNER JOIN
	tb_member_level AS ml
	ON 
	ml.level_num = m.m_level
WHERE
	ml.level_name NOT LIKE '%관리자%'
GROUP BY l.login_id
HAVING COUNT(l.login_id) > (SELECT 
								ROUND(AVG(cAvg.로그인횟수),1) AS '평균로그인횟수'
                                FROM
                                    (SELECT
                                          l.login_id AS '아이디'
                                          ,COUNT(l.login_id) AS '로그인횟수'
                                      FROM
                                          tb_login AS l
                                       INNER JOIN 
                                          tb_member AS m
                                       ON 
                                          m.m_id =  l.login_id
                                       INNER JOIN
                                          tb_member_level AS ml
                                       ON 
                                          ml.level_num = m.m_level
                                       WHERE
                                          ml.level_name NOT LIKE '%관리자%'
                                       GROUP BY l.login_id ) AS cAvg);
SELECT
	m.m_id AS '회원아이디'
	,COUNT(*) AS '로그인횟수'
FROM
		tb_member AS m
		INNER join
		tb_login AS l
		ON
		m.m_id = l.login_id
		and
		m.m_level > 1
GROUP BY m.m_id
HAVING COUNT(*) >
		(/*회원 평균 로그인 회수*/
		SELECT
			AVG(avg_login.로그인횟수)
		FROM
		(/*회원별 로그인 횟수*/
			SELECT
				m.m_id
				,COUNT(*) AS '로그인횟수'
			FROM
				tb_member AS m
				INNER join
				tb_login AS l
				ON
				m.m_id = l.login_id
				and
				m.m_level > 1
			GROUP BY m.m_id) AS avg_login)

--변수활용

SELECT
	result.m_id
	,result.로그인횟수
from	
	(SELECT
		m.m_id
		,COUNT(*) AS '로그인횟수'
		,@sumlogin := @sumlogin + COUNT(*)
		,@cnt := @cnt+1
	
	FROM
		tb_member AS m
		INNER join
		tb_login AS l
		on
		m.m_id = l.login_id
		and
		m.m_level >1
		join
		(SELECT @sumlogin := 0, @cnt := 0) AS c
	GROUP BY m.m_id) AS result	
WHERE 
	result.로그인횟수 > (@sumlogin/@cnt)

DML (4) - 회원 별 구매이력 중 구매금액이 가장 높은 상위 30%만 조회하시오.

SELECT
	*
from
	(SELECT
		(case 
		when @gPrice = result.amt then @rank
		when @gPrice := result.amt then @rank := @checked + 1
		END ) AS rank
		,result.o_id
		,result.amt
		,@checked := @checked +1 AS cnt
	from
		(SELECT
			o.o_id
			,SUM(g.g_price*o.o_amount) AS amt
		FROM
			tb_order AS o
			INNER JOIN
			tb_goods AS g
			on
			o.o_g_code = g.g_code
		GROUP BY o.o_id	
		ORDER BY amt DESC) AS result
		join
		(SELECT @gPrice := 0, @rank := 0, @checked := 0) AS r) AS total
WHERE
	total.rank <= (@checked * 0.3)

profile
기록하는 삶
post-custom-banner

0개의 댓글