SQL

05. [SQL] SELECT문

프로그린 2024. 4. 7. 23:52

USE 구문

  • SELECT문 학습 위해 사용할 데이터베이스 지정
  • 지정해 놓은 후 다른 DB를 사용하겠다고 명시하지 않는 이상 모든 SQL문은 지정된 DB에서 수행
USE `데이터베이스 이름`;
use employees;

 
SELECT ... FROM

  • 데이터베이스 내 테이블에서 원하는 정보를 추출
  • 테이블에 있는 모든 정보 조회
SELECT * FROM `테이블 이름`;
select * from employees;
  • 테이블에서 필요로 하는 열만 가져오기
SELECT `열 이름` FROM `테이블 이름`;
select first_name from employees;
  • 여러 개의 열을 가져오고 싶을 때는 콤마로 구분
  • 열 이름의 순서는 출력하고 싶은 순서대로 배열 가능
SELECT 열1, 열2, 열3 FROM `테이블 이름`;
select first_name, last_name, gender from employees;

 
주석(Remark)

  • 한 줄 주석처리 --
    • -- 뒤에 하나 이상의 공백이 있어야 함.
-- 한 줄 주석
  • 여러 줄 주석처리 /* */
/* 블록주석
   여러줄 주석
*/

 

DB, TABLE, 열의 이름이 확실하지 않을 때 조회하는 방법

  • 현재 서버에 어떤 DB가 있는지 조회
SHOW DATABASES;
  • 현재 DB에 있는 TABLE 정보 조회
SHOW TABLE STATUS;
  • 현재 DB에 있는테이블 이름만 간단히 보기
SHOW TABLES;
  • 테이블에 있는 열 정보 확인
DESCRIBE 테이블 이름 ; 
DESC 테이블 이름;

 
 
열 이름에 별칭 지정하기

열이름 as 별칭
  • as는 생략가능, 별칭 내에 공백이 있다면 ` `(백틱)으로로 묶어줘야 함. ' '(따옴표)와 구별에 주의
select first_name as 이름,
		gender as 성별,
		hire_date as `회사 입사일`
    from employees;

 
SELECT ... FROM ... WHERE

  • 특정 조건의 데이터만 조회
SELECT `열 이름` FROM `테이블 이름` WHERE 조건식;
select * from usertbl where name = '김경호';
Q1. 이름이 김범수인 사람을 찾아라.
select * from usertbl where name = '김범수';​

Q2. 이름이 조관우인 사람을 찾아라.
select * from usertbl where name = '조관우';​

Q3. 주소지가 서울인 사람을 찾아라.
select * from usertbl where Addr = '서울';​

Q4. 출생년도가 1973인 사람을 찾아라.
select * from usertbl where birthYear = 1973;​

Q5. Mobile1의 정보가 없는 사람을 찾아라.
select * from usertbl where mobile1 is null;​

 
관계 연산자를 사용한 특정 조건의 데이터 조회

  • 조건 연산자(=, <, >, <=, >=, <>, != 등)와 관계 연산자(NOT, AND, OR 등)를 조합하여 데이터를 효율적으로 추출 가능
Q1. 1970년 이후에 출생하고, 신장이 182 이상인 사람의 모든 정보를 조회하라.
select * from usertbl where birthYear >= 1970 and height >= 182;​

Q2.1970년 이후에 출생하고, 신장이 182 이상인 사람의 아이디와 이름을 조회하라.
select userID, name from usertbl where birthYear >= 1970 and height >= 182;​

Q3. 주소지가 서울인 사람들의 모든 정보를 조회하라.
select * from usertbl where addr = '서울';​

Q4. 주소지가 서울이면서 mobile1의 번호를 011로 사용하는 사람의 모든 정보를 조회하라.
select * from usertbl where addr = '서울' and mobile1 = 011;​

Q5. 주소지가 서울이면서 mobile1의 번호를 011로 사용하는 사람의 아이디, 이름, mobile1과 mobile2를 조회하라.
select userID, name, mobile1, mobile2 from usertbl where addr = '서울' and mobile1 = 011;​

Q6. 위의 결과 중 mobile1과 mobile2 사이에 구분자(-)를 넣어서 phonenumber라는 하나의 열로 나타내라.
select userID, name, concat(mobile1, '-' ,mobile2) as phonenumber
	from usertbl
    where addr = '서울' and mobile1 = 011;​

 

  • BETWEEN... AND : 데이터가 숫자로 구성되어 있으며 연속적인 값일 때
Q. 키가 180에서 183 사이인 사람들의 이름과 키를 출력하라.
select name, height from usertbl where height between 180 and 183;​
  • IN () : 이산적인 값의 조건을 나타낼 때
Q. 주소지가 경남, 전남, 경북 중 하나인 사람들의 이름과 주소를 출력하라.
select name, addr from usertbl where addr in ('경남', '전남', '경북');​
  • LIKE : 문자열의 내용 검색
    • % : 무엇이 오든 제한없이 허용
    •  _ : 한 글자와 매치
Q. 이름의 두번째 글자가 '용'인 사람의 이름을 출력하라.
select name from usertbl where name like '_용%';

 

 
서브쿼리(SubQuery, 하위쿼리)

  • 쿼리문 안에 또 쿼리문이 들어있는 것
  • 서브쿼리 결과가 2개 이상이면 에러가 발생하므로 ANY, SOME, ALL 등과 함께 사용
Q. 김경호보다 키가 큰 사람의 이름과 키를 출력하라.
select name, height from usertbl
	where height > (select height from usertbl where name = '김경호');​

 

  • ANY/SOME
    • 서브쿼리의 여러 개의 결과 중 한 가지만 만족해도 가능
    • = 'ANY(서브쿼리)'와 'IN(서브쿼리)'는 동일한 의미
Q. 지역이 경남인 사람의 키보다 큰 사람의 이름과 키를 출력하라. (any 사용)
select name, height from usertbl
	where height > any (select height from usertbl where Addr = '경남');​

>> 지역이 경남인 사람 중 어느 한사람보다만 크면 되므로 키가 제일 작은 170 보다 큰 사람들이 출력됨.

  • ALL
    • 서브쿼리의 결과 중 여러개의 결과를 모두 만족해야 함.
Q. 지역이 경남인 사람 누구의 키보다 큰 사람의 이름과 키를 출력하라. (all 사용)
select name, height from usertbl
	where height > all (select height from usertbl where Addr = '경남');​

>> 지역이 경남인 사람 누구보다 커야 하므로 키가 제일 큰 173 보다 큰 사람들이 출력됨.

 
원하는 순서대로 정렬하여 출력 : ORDER BY

  • 결과물에 대해 영향을 미치지는 않고 출력되는 순서를 조절
  • 오름차순으로 정렬하려면 열 이름 뒤에 ASC, 내림차순으로 정렬하려면 열 이름 뒤에 DESC를 붙임.
  • 기본값이 오름차순이므로 ASC는 생략 가능
  • 조건을 여러 개로 설정하여 정렬하는 것도 가능
Q. 키가 큰 순서로 정렬하되 만약 키가 같을 경우 이름 순으로 정렬하라.
select name, height from usertbl order by height desc, name asc;​

 
중복된 값에 대한 처리 : DISTINCT

  • 중복된 것을 유니크한 값으로 처리
  • 테이블의 크기가 클수록 효율적
  • DISTINCT 뒤에 여러개를 나열하면 모든 열에 적용됨.
Q. usertbl의 지역들을 중복없이 출력하라.
select distinct addr from usertbl;​

 
출력의 개수를 제한 : LIMIT

  • 일부를 보기 위해 여러 건의 데이터를 출력하는 부담을 줄임
  • 상위 N개의 데이터만 보고싶다면 limit N 사용
Q. employees 테이블에서 입사일이 오래된 5명의 사번과 입사일을 입사일이 오래된 순서대로 출력하라.
select emp_no, hire_date
	from employees
    order by hire_date asc
    limit 5;

 
테이블 복사하기 : CREATE TABLE ... SELECT

  • 테이블을 복사해서 사용할 경우 주로 사용
  • 지정한 일부 열만 복사하는 것도 가능
  • PK나 FK같은 제약 조건은 복사되지 않음.
CREATE TABLE `새로운 테이블` (SELECT `복사할 열` FROM `기존 테이블`);
Q1. sqldb의 buytbl 테이블을 buytbl2로 복사하라.
use sqldb;
create table buytbl2 (select * from buytbl);​

Q2. buytbl 테이블 중 userID와 prodName 열만 buytbl3로 복사하라.
create table buytbl3 (select userID, prodName from buytbl);​

 

GROUP BY ... HAVING

  • 그룹으로 묶어주는 역할
  • 집계 함수(Aggregate Function)와 함께 사용
  • GROUP BY 와 함께 자주 사용되는 집계 함수
함수명설명
AVG()평균
MIN()최소값
MAX()최대값
COUNT()행의 개수
COUNT(DISTINCT)중복을 제외한 행의 개수
STDEV()표준편차
VAR_SAMP()분산
Q. 각 사용자 별로 구매한 물품의 총 구매액을 ID의 사전 순서대로 출력하라.
select userID as `사용자 아이디`, sum(amount * price) as `총 구매 개수`
	from buytbl
    group by userID
    order by userID;​
  • HAVING절
    • WHERE와 비슷한 개념으로 GROUP BY절 뒤에서 집계 함수에 대해서 조건을 제한
Q. 총 구매액이 1000 이상인 회원의 ID와 총 구매액을 총 구매액이 큰 것부터 순서대로 출력하라.
select userID as `사용자 아이디`, sum(price * amount) as `총 구매액`
	from buytbl
    group by userID
    having sum(price * amount) > 1000
    order by sum(price * amount) desc;​

 

ROLLUP

  • 총합 또는 중간 합계가 필요한 경우 사용
  • GROUP BY와 함께 WITH ROLLUP문 사용
Q. buytbl의 groupName 분류별 구매액 및 총합을 구하라.
select groupName, sum(price * amount) as `총 구매액`
	from buytbl
	group by groupName
	with rollup;​

 


Reference : 이것이 MySQL이다