실무에서는 SELECT *는 디버깅 외엔 지양(네트워크/IO 비용 증가).
-- (나쁜 습관) 전체 컬럼
SELECT * FROM customers;
-- (권장) 필요한 컬럼만
SELECT customer_id, email, name, status, created_at
FROM customers;
select name,phome,status from customers;
select sku,name,price from products;
SELECT
product_id AS id,
name AS product_name,
price,
stock,
price * stock AS stock_value
FROM products;
price * 1.1을 vat_included_price로 계산해 조회하라.select
price * 1.1 as vat_included_price
from products;
SELECT DISTINCT category
FROM products;
select distinct status from orders;
SELECT customer_id, name, created_at
FROM customers
ORDER BY created_at DESC;
SELECT product_id, name, created_at
FROM products
ORDER BY created_at DESC
LIMIT 5; // 상위 5개 제한
select * from products
order by price desc
limit 10; // 상위 10개 제한
SELECT product_id, category, name, price
FROM products
ORDER BY category ASC, price DESC, name ASC;
select name,category,price from products
order by category asc, price desc;
SELECT product_id, name, price
FROM products
WHERE price >= 50000;
SELECT product_id, name, stock
FROM products
WHERE stock >= 100;
SELECT product_id, name, price
FROM products
WHERE price < 10000;
-- 1만원~5만원 사이
SELECT product_id, name, price
FROM products
WHERE price BETWEEN 10000 AND 50000; // 10000이상 50000이하
-- 특정 카테고리만
SELECT product_id, name, category
FROM products
WHERE category IN ('DEVICE','STORAGE');
-- 힌트
-- WHERE ordered_at >= NOW() - INTERVAL 7 DAY
select * from orders
where ordered_at >= now() - interval 7 day;
-- name에 'Cable'이 포함된 상품
SELECT product_id, name
FROM products
WHERE name LIKE '%Cable%';
VALUE에
%가 들어간다면\%로 검색하면된다.
예) 50%,60%를 검색 -> WHERE name LIKE '%0\%%'
email이 user1로 시작하는 고객을 조회하라.
(예: user10@example.com, user11@example.com등)
SELECT * FROM customers
WHERE email LIKE 'user1%';
현재 샘플은 phone이 모두 존재하지만, 실무 필수 문법이므로 형태만 익힌다.
SELECT customer_id, name, phone
FROM customers
WHERE phone IS NULL;
SELECT customer_id, name, phone
FROM customers
WHERE phone IS NOT NULL;
SELECT product_id, category, name, price
FROM products
WHERE (category = 'DEVICE' OR category = 'STORAGE')
AND price >= 100000;
SELECT product_id, category, name, price
FROM products
WHERE category = 'ACCESSORY' AND (price between 10000 and 30000);
-- 상품 평균 가격
SELECT round(AVG(price),1) AS avg_price
FROM products;
-- 최고/최저 가격
SELECT MIN(price) AS min_price, MAX(price) AS max_price
FROM products;
-- 전체 재고 합
SELECT SUM(stock) AS total_stock
FROM products;
select count(*) as order_count from orders;
select count(*) as payments_cnt from payments;
SELECT
category,
COUNT(*) AS product_count,
AVG(price) AS avg_price
FROM products
GROUP BY category
ORDER BY product_count DESC;
SELECT
category,
SUM(stock) AS total_stock,
FROM products
GROUP BY category;
SELECT
status,
count(*) AS order_count,
FROM orders
GROUP BY status;
WHERE는 “행(row) 필터”, HAVING은 “그룹 결과 필터”
-- 상품이 3개 이상인 카테고리만
SELECT category, COUNT(*) AS cnt
FROM products
GROUP BY category
HAVING COUNT(*) >= 3
ORDER BY cnt DESC;
select status, count(*) as cnt from orders
group by status
having cnt >= 2;
조회/필터/정렬/집계를 한 번에 사용
SELECT order_id, customer_id, status, ordered_at, total_amount
FROM orders
WHERE ordered_at >= NOW() - INTERVAL 14 DAY
AND status <> 'CANCELLED'
ORDER BY ordered_at DESC
LIMIT 20;
SELECT customer_id, COUNT(*) AS order_cnt
FROM orders
GROUP BY customer_id
ORDER BY order_cnt DESC
LIMIT 5;
SELECT method, SUM(paid_amount) AS total_paid
FROM payments
GROUP BY method
ORDER BY total_paid DESC;
SELECT status, SUM(total_amount) AS total_sales
FROM orders
GROUP BY status
ORDER BY total_sales DESC;
SELECT AVG(total_amount) AS avg_order_amount
FROM orders
WHERE status <> 'CANCELLED';
SELECT COUNT(*) AS high_value_orders
FROM orders
WHERE total_amount >= 100000;
WHERE는 개별 행 필터, HAVING은 그룹 결과 필터ORDER BY는 최종 결과 정렬 (WHERE/GROUP BY 이후)Q1. customers 테이블에서 ACTIVE 고객만 조회하고, created_at 최신순으로 10명만 출력하시오.
(출력: customer_id, email, name, created_at)
select customer_id, email, name ,created_at from customers
where status = "ACTIVE"
order by created_at desc
limit 10;
Q2. products에서 category='STORAGE' 인 상품 중 price >= 150000 인 상품을 가격 내림차순으로 조회하시오.
(출력: product_id, sku, name, price)
select product_id,sku,name,price from products
where category = 'STORAGE' and price >= 150000
order by price desc;
Q3. products에서 stock <= 30 인 “재고 부족” 상품을 stock 오름차순으로 조회하시오.
(출력: product_id, name, stock)
select product_id,name,stock from products
where stock<=30
order by stock asc;
Q4. orders에서 status='CANCELLED' 주문만 조회하시오. (출력: order_id, customer_id, ordered_at)
select order_id,customer_id,ordered_at from orders
where status='CANCELLED';
Q5. orders에서 최근 7일 이내 주문을 조회하시오. (출력: order_id, customer_id, status, ordered_at)
select order_id,customer_id,status,ordered_at from orders
where ordered_at >= now() - interval 7 day
order by ordered_at desc;
Q6. customers에서 email이 user% 패턴인 고객을 조회하시오. (출력: customer_id, email, name)
select customer_id, email, name from customers
where email like ('user%');
Q7. orders에서 total_amount가 100,000 이상인 주문을 total_amount 내림차순으로 조회하시오.
(출력: order_id, total_amount)
select order_id, total_amount from orders
where total_amount >=100000
order by total_amount desc;
Q8. products에서 name에 “Cable”이 포함된 상품을 조회하시오. (출력: product_id, name)
select product_id,name from products
where name like('%Cable%');
Q9. payments에서 결제수단별(method) 결제 건수를 조회하시오. (출력: method, cnt)
select method, count(*) as cnt from payments
group by method;
Q10. orders에서 status별 주문 건수를 조회하고, 건수 내림차순 정렬하시오. (출력: status, cnt)
select status, count(*) as cnt from orders
group by status
order by cnt desc;
Q11. orders에서 주문일(ordered_at)을 날짜(YYYY-MM-DD)로만 보여 주문일별 주문 건수를 조회하시오.
(출력: order_date, cnt)
SELECT
DATE(ordered_at) AS order_date,
COUNT(*) AS cnt
FROM orders
GROUP BY DATE(ordered_at)
ORDER BY order_date;
Q12. payments에서 결제일(paid_at) 기준 월(YYYY-MM)별 결제 합계를 조회하시오.
(출력: pay_month, total_paid)
SELECT
DATE_FORMAT(paid_at, '%Y-%m') AS pay_month,
SUM(paid_amount) AS total_paid
FROM payments
GROUP BY DATE_FORMAT(paid_at, '%Y-%m')
ORDER BY pay_month;
Q13. customers에서 가입일(created_at) 기준 “며칠 전 가입했는지”를 day_diff로 출력하시오.
(출력: customer_id, name, day_diff)
SELECT
customer_id,
name,
DATEDIFF(CURDATE(), DATE(created_at)) AS day_diff
FROM customers
ORDER BY day_diff desc;
Q14. products에서 카테고리별 평균가격(AVG)과 최고가(MAX), 최저가(MIN)를 조회하시오.
(출력: category, avg_price, max_price, min_price)
SELECT
category,
AVG(price) AS avg_price,
MAX(price) AS max_price,
MIN(price) AS min_price
FROM products
GROUP BY category;
Q15. orders에서 주문금액 구간을 분류해(CASE) 집계하시오.
SELECT
CASE
WHEN total_amount BETWEEN 0 AND 49999 THEN 'LOW'
WHEN total_amount BETWEEN 50000 AND 199999 THEN 'MID'
ELSE 'HIGH'
END AS bucket,
COUNT(*) AS cnt
FROM orders
GROUP BY bucket
ORDER BY bucket;
Q16. customers에서 phone이 NULL인 고객 수를 조회하시오.
SELECT
COUNT(*) AS cnt
FROM customers
WHERE phone IS NULL;
Q17. products에서 sku가 'SKU-10%' 인 상품 수를 조회하시오.
SELECT
COUNT(*) AS cnt
FROM products
WHERE sku LIKE 'SKU-10%';
Q18. orders에서 고객별 평균 주문금액을 구하되, 주문이 2건 이상인 고객만 출력하시오.
(출력: customer_id, avg_amount, order_cnt)
SELECT
customer_id,
AVG(total_amount) AS avg_amount,
COUNT(*) AS order_cnt
FROM orders
GROUP BY customer_id
HAVING COUNT(*) >= 2
ORDER BY customer_id;
Q19. payments에서 결제수단별 평균 결제금액을 조회하시오. (출력: method, avg_paid)
SELECT
method,
AVG(paid_amount) AS avg_paid
FROM payments
GROUP BY method
ORDER BY method;
Q20. order_items에서 주문당 총 수량(quantity 합)을 구하고, 총 수량이 4 이상인 주문만 출력하시오.
(출력: order_id, total_qty)
SELECT
order_id,
SUM(quantity) AS total_qty
FROM order_items
GROUP BY order_id
HAVING SUM(quantity) >= 4
ORDER BY order_id;