[SQL] SELECT - ORDER BY, WHERE, DISTINCT, LIMIT

제훈·2024년 6월 24일
0

SW공학, DB

목록 보기
6/21

MariaDB에 대해
MariaDB에 대해 하면서 SELECT 절에 대해서 이어서 해보려고 한다.

SQL query 실행순서

ORDER BY 절

ORDER BY 절은 정렬할 때 사용하는 절로
Ascending (오름차순) 과 Descending (내림차순) 2가지 방법으로 속성들을 정렬할 수 있다.

정렬의 Default는 오름차순이다.

  1. 가격을 기준으로 오름차순 정렬하기
SELECT
		 menu_code
	  , menu_name
	  , menu_price
	FROM tbl_menu
  ORDER BY menu_price ASC;

  1. 가격을 기준으로 오름차순 (가격이 같다면 메뉴명의 내림차순으로 정렬)
SELECT
		 menu_code
	  , menu_name
	  , menu_price
	FROM tbl_menu
  ORDER BY menu_price ASC, menu_name DESC;


별칭(alias)을 이용한 정렬

AS 을 활용해서 매번 길게 적을 필요 없다.
menu_pricemp로 별칭 활용해 내림차순 정렬해보았다.

SELECT
		 menu_code AS '메뉴코드'
	  , menu_name AS 'MN'
	  , menu_price AS 'MP'
	FROM tbl_menu
  ORDER BY mp DESC;


field 를 활용한 정렬

field는 (orderable_status, 'N', 'Y') 에서
orderable_status 가 N이면 1을, Y면 2를 넣어주는데 이것을 활용해서 N, Y로 정렬할 수 있다.

주문 가능한 것부터 보이게 정렬하기

SELECT
		 menu_name
	  , orderable_status
  FROM tbl_menu
 ORDER BY FIELD(orderable_status, 'N', 'Y') DESC;

내림차순으로 Y를 위로 올려보내줬다.


null 값에 대해 정렬하기

-- 1) 오름차순 식 - null 값이 먼저
SELECT
		 *
  FROM tbl_category
 ORDER BY ref_category_code ASC;
 
-- 2) 내림차순 식 - null이 나중에
SELECT
		 *
  FROM tbl_category
 ORDER BY ref_category_code DESC;

-- 3) 오름차순에서 null이 나중에 나오게 바꾸기
SELECT
		 *
  FROM tbl_category
 ORDER BY -ref_category_code DESC;
 
 -- 4) 내림차순에서 null이 먼저 나오게 하기
SELECT
		 *
  FROM tbl_category
 ORDER BY -ref_category_code ASC;

(-)를 붙이면 데이터값은 반대로 정렬되지만 null 값은 그대로 유지된다.

  1. 내림차순인 DESC 지만 -가 붙어서 오름차순 + null값이 마지막
  2. 오름차순인 ASC 지만 -가 붙어서 내림차순 + null이 처음

즉 order by만 있다면 from -> select -> order by 순서대로 이뤄진다.


Where 절

내용에 따른 참조에 대한 내용을 해볼 것이다.
Where 절은 조건문이라고 생각하면 된다.

SELECT
		 menu_name
	  , menu_price
	  , orderable_status
  FROM tbl_menu
 WHERE orderable_status = 'Y';
 -- WHERE orderable_status = 'N';

주문 상태가 주문 가능한지 조건문을 달아서 확인할 수 있다.

--  '기타' 카테고리에 해당하지 않는 메뉴를 조회해보자
SELECT
		 *
  FROM tbl_category
 WHERE category_name = '기타'; -- 이것으로 일단 '기타' 카테고리인 메뉴를 찾고

-- 해당하는 메뉴를 제외하고 조회하면 된다. (10번임)

SELECT
		 *
  FROM tbl_menu
 WHERE category_code != 10;
 -- WHERE category_code <> 10;

!= 또는 <> 라는 표시는 같은 의미이다. ("같지 않다" 는 의미)
대소 비교 (>, <, >=, <=) 또한 where 절에서 사용 가능

SELECT
		 *
  FROM tbl_menu
 WHERE menu_price >= 5000;
 -- ORDER BY menu_price ASC;

이렇게 대소비교도 가능한데, 만약 price 가 5000보다 크거나 같고, 10000보다 작은걸 찾고 싶다면 어떻게 해야 할까?

WHERE 5000 <= menu_price < 10000 하면 되는거 아닌가? -> X 안 된다.
SQL은 삼항 연산이 되지 않는다. 그걸 해결하기 위해 있는 것이

논리 연산자 AND, OR 이다. 당연히 이번에는 AND를 써야 한다.

SELECT
		 *
  FROM tbl_menu
 WHERE menu_price >= 5000 
   AND menu_price < 10000
 ORDER BY menu_price ASC;

OR을 사용했을 때의 경우다. (10000원 초과 또는 5000원 이하인 메뉴)

SELECT
		 *
  FROM tbl_menu
 WHERE menu_price > 10000 
    OR menu_price <= 5000
 ORDER BY menu_price ASC;

Between 연산

<=, >= 로 나타낼 때 길어지는 것때문에 만든 연산자이다.

-- 가격이 5000원 이상이면서 9000원 이하인 메뉴 전체 컬럼 조회
SELECT
		 *
  FROM tbl_menu
 WHERE menu_price BETWEEN 5000 AND 9000;

반대인 경우엔? -> not 을 붙여라.

SELECT
		 *
  FROM tbl_menu
 WHERE menu_price NOT BETWEEN 5000 AND 9000;

Like 문

제목, 작성자 등 DB 값 중에서 특정 단어를 검색할 때 사용한다.

SELECT
		 *
  FROM tbl_menu
 WHERE menu_name LIKE '밥%';
 -- WHERE menu_name LIKE '%밥';
 -- WHERE menu_name LIKE '%밥%';

밥% : "밥"으로 시작하는 것을 검색할 때 ex) "밥OOO"
%밥 : "밥"으로 끝나는 것을 검색할 때 ex) "OOO밥"
%밥% : "밥"이라는 글자가 들어가는 것을 검색할 때 ex) "OO밥OO"


in연산자

SELECT
		 *
  FROM tbl_menu
 WHERE category_code = 5
    OR category_code = 8
    OR category_code = 10;

이렇게 OR을 이용하는 것이 불편하기 때문에 in 연산자로 간단하게 나타낼 수 있다.

SELECT
		 *
  FROM tbl_menu
 WHERE category_code IN (5, 8, 10);

반대인 경우엔? -> not 을 붙여라.

```sql
SELECT
		 *
  FROM tbl_menu
 WHERE category_code NOT IN (5, 8, 10);

IS NULL 연산자 활용

상위 카테고리를 조회하는 방법으로 사용한다.

SELECT
		 *
  FROM tbl_category
 WHERE ref_category_code IS NULL;

하위 카테고리를 조회하려면? -> NOT을 붙여라. -> IS NOT NULL

SELECT
		 *
  FROM tbl_category
 WHERE ref_category_code IS NOT NULL;

  • 각 테이블의 컬럼명을 빠르게 확인하는 방법

DESC (컬럼명 확인)

DESC tbl_menu;


DISTINCT

간단하게 말해 조회할 때 중복되는 값들을 없애고 1개 값만 나타낼 때 사용한다.

Distinct 없이는 값이 중복돼 나오지만

중복을 없앨 수 있다.


다중 열 DISTINCT

SELECT 절에서 맨 앞에 DISTINCT 를 적으면 하나만 중복이 없어지는 것이 아니라, 여러 개의 열을 적어도 같이 중복 제거가 된다.

(자주 쓰이지는 않는다)


LIMIT

페이징 처리나 원하는 범위만큼 잘라서 보내주고 싶을 때 사용하는 LIMIT이다.

LIMIT은 조회하고 싶은 개수를 선정하고 싶을 때 ORDER BY 절에서 사용하는 것이다.
예를 들어 menu 테이블 안에 행들을 가격순으로 조회해보자.

여기에서 내가 상위 3개만 골라오고 싶다면?

SELECT
		 menu_code
	  , menu_name
	  , menu_price
  FROM tbl_menu
 ORDER BY menu_price DESC
 LIMIT 3;


만약 5~7번까지 가져오고 싶다면?
LIMIT은 index 형태로 나타내기 때문에 5번부터 3개라는건
인덱스로 4, 가져오는건 3
즉, LIMIT 4, 3 으로 나타내면 된다.

SELECT
		 menu_code
	  , menu_name
	  , menu_price
  FROM tbl_menu
 ORDER BY menu_price DESC
 LIMIT 4, 3;


LIMIT 시 재정렬에 대한 궁금증

여기서 궁금증이 생겼다.
원래 전체 행 조회했을 때는 13000원으로 가격이 같은 행은 ORDER BY 로 정렬하면

14 과메기 커틀릿
5 앙버터김치찜

순서였는데 LIMIT 4, 3 으로 잘랐을 때는

5 앙버터김치찜
14 과메기 커틀릿

이것과 같은 순서가 된다. 왜지??

알아보니 LIMIT은 ORDER BY된 것들을 가지고 또 정렬을 하는데,
LIMIT이 없을 때와 LIMIT이 있을 때의 정렬하는 내부 알고리즘에서 약간의 차이가 있어서 생기는 순서변화라고 한다.

순서가 중요하다면 ORDER BY에 하나 더 속성을 추가해야된다고 한다.

참고 링크 : https://dev.mysql.com/doc/refman/5.7/en/limit-optimization.html

즉, LIMIT이 포함된 ORDER BY랑 단순 ORDER BY는 정렬 기준 컬럼의 값이 같으면 약간의 순서 차이가 있을 수 있다

profile
백엔드 개발자 꿈나무

0개의 댓글