컴퓨터 활용/노년에 즐기는 코딩

MySQL 8.x 기준 내장 함수 핵심 정리

easyfly 2025. 11. 6. 11:22
반응형

다음은 MySQL 8.x 기준 내장 함수 핵심 정리와 실무 예시입니다. 범주별로 대표 문법, 사용 팁, 주의점을 함께 묶었습니다. 

 


1) 문자열 함수 (String)

  • 길이/자르기
  • SELECT LENGTH('한글'), CHAR_LENGTH('한글'); -- 바이트/문자 수(UTF-8에서 다름) SELECT LEFT('abcdef',3), RIGHT('abcdef',2); SELECT SUBSTRING('가나다라마바사',3,2); -- '다라'
  • 검색/치환/결합
  • SELECT INSTR('bananA','na'); -- 3 (1부터 시작) SELECT LOCATE('na','banana',4); -- 5 (시작 위치 지정) SELECT REPLACE('a,b,c', ',', '|'); -- 'a|b|c' SELECT CONCAT('Hello ', UPPER('mysql')); -- 'Hello MYSQL' SELECT CONCAT_WS('-', '2025','07','20'); -- '2025-07-20'
  • 공백/패딩/정렬
  • SELECT TRIM(' x '), LTRIM(' x'), RTRIM('x '); SELECT LPAD('7',3,'0'), RPAD('A',5,'*'); -- '007', 'A****'
  • 비교/정규표현식
  • SELECT 'abc' REGEXP '^[a-z]+$'; -- 1(일치), 0(불일치), NULL SELECT REGEXP_REPLACE('010-1234-5678','-',''); -- '01012345678'

: 한글 길이는 CHAR_LENGTH()로, 바이트 계산은 LENGTH()로 확인하십시오. 정규식은 8.0에서 개선되었으며 ICU 엔진을 사용합니다.


2) 수치 함수 (Numeric)

  • 절대값/반올림
  • SELECT ABS(-3.14), ROUND(3.14159,2), CEIL(2.1), FLOOR(2.9);
  • 나머지/난수
  • SELECT MOD(10,3); -- 1 SELECT RAND(), RAND(42); -- 시드 고정 가능(재현성)
  • 합성/로그/지수
  • SELECT POW(2,10), EXP(1), LN(10), LOG10(1000);

: ROUND(x,0)은 정수 반올림, TRUNCATE(x,d)는 절삭입니다.


3) 날짜·시간 함수 (Date/Time)

  • 현재 시각
  • SELECT NOW(), CURRENT_DATE(), CURRENT_TIME();
  • 구성/파싱
  • SELECT MAKEDATE(2025, 200); -- 2025-07-19 SELECT MAKETIME(14,30,0); -- 14:30:00 SELECT STR_TO_DATE('2025/07/20','%Y/%m/%d');
  • 연산/차이
  • SELECT DATE_ADD('2025-07-20', INTERVAL 7 DAY); SELECT TIMESTAMPDIFF(DAY, '2025-07-01', '2025-07-20'); -- 19 SELECT DATEDIFF('2025-07-20','2025-07-01'); -- 19
  • 부분 추출/형식화
  • SELECT YEAR(NOW()), MONTH(NOW()), DAY(NOW()); SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i');

주의: 타임존을 사용한다면 세션 변수 time_zone을 확인하십시오. 애플리케이션은 UTC 저장, 현지 시간 변환을 권장합니다.


4) 집계 함수 (Aggregate)

  • 기본
  • SELECT COUNT(*), COUNT(col), SUM(col), AVG(col), MIN(col), MAX(col) FROM t; SELECT GROUP_CONCAT(name ORDER BY name SEPARATOR ', ') FROM users;

NULL 규칙: COUNT(col)은 NULL을 제외하고 세며, SUM/AVG는 모든 값이 NULL이면 NULL을 반환합니다(필요 시 COALESCE로 대체값 지정).


5) 윈도 함수 (Window / OLAP, 8.0+)

  • 누계/순위
  • SELECT emp, dept, salary, SUM(salary) OVER (PARTITION BY dept ORDER BY salary ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS run_sum, RANK() OVER (PARTITION BY dept ORDER BY salary DESC) AS rk FROM employees;
  • 집계 유지한 채 상세 행까지 함께 조회할 때 유용합니다.
    성능 팁: PARTITION BY/ORDER BY에 맞는 인덱스를 고려하십시오.

6) 조건·흐름 제어 (Conditional)

SELECT IF(1<2, 'Y','N');                   -- 스칼라 if
SELECT IFNULL(col, 'N/A'), COALESCE(a,b,0);
SELECT CASE
         WHEN score >= 90 THEN 'A'
         WHEN score >= 80 THEN 'B'
         ELSE 'C'
       END AS grade;

SARGability: WHERE 절에서 컬럼에 함수를 감싸면 인덱스를 못 탈 수 있습니다. 가능하면 상수를 변환하는 방식으로 작성하십시오.
예) WHERE date_col >= CURDATE()(좋음) vs WHERE DATE(date_col) = CURDATE()(인덱스 사용 불리).


7) 변환·캐스팅 (Type/Collation)

SELECT CAST('123' AS UNSIGNED), CONVERT('2025-07-20', DATETIME);
SELECT CONVERT('abc' USING utf8mb4);        -- 문자셋 변환

한글 정렬: COLLATE utf8mb4_0900_ai_ci 등 정렬규칙에 따라 대/소문자·악센트·자모 분해 처리 등이 달라집니다.


8) JSON 함수 (8.0 필수 기능)

  • 생성/접근
  • SELECT JSON_OBJECT('name','홍길동','age',70); -- {"name":"홍길동","age":70} SELECT JSON_EXTRACT('{"a":1,"b":[10,20]}', '$.b[1]'); -- 20 SELECT JSON_UNQUOTE(JSON_EXTRACT(jdoc, '$.name')) FROM t;
  • 수정/머지/검색
  • SELECT JSON_SET('{"a":1}', '$.b', 2); -- {"a":1,"b":2} SELECT JSON_MERGE_PATCH('{"a":1}', '{"a":9,"c":3}');-- {"a":9,"c":3} SELECT JSON_SEARCH('["사과","배","포도"]','one','배'); -- 경로 반환
  • 인덱싱(생성 컬럼 + 함수 인덱스)
  • ALTER TABLE orders ADD COLUMN cust_id INT GENERATED ALWAYS AS (JSON_EXTRACT(doc,'$.custId')) STORED, ADD INDEX idx_cust_id (cust_id);

: 쿼리에서 자주 꺼내는 JSON 키는 생성(가상/저장) 컬럼 + 인덱스로 최적화하십시오.


9) 보안·해시·암호화

SELECT SHA2('text',256);
SELECT MD5('text');                    -- 충돌 위험, 무결성 확인 외엔 비권장
SELECT AES_ENCRYPT('secret','key'), AES_DECRYPT(aes_col,'key');

주의: 사용자 비밀번호는 애플리케이션 층에서 강력한 해시(예: bcrypt/Argon2)를 사용하십시오. DB 내 단순 해시는 지양합니다.


10) 정보 함수 (메타/상태)

SELECT VERSION(), CONNECTION_ID(), DATABASE(), USER();
SELECT ROW_COUNT();      -- 직전 DML 영향 행수
SELECT LAST_INSERT_ID(); -- AUTO_INCREMENT 마지막 값(세션별)

11) 공간(GIS)·텍스트

  • 공간(옵션): ST_Distance, ST_Contains, ST_AsText, ST_GeomFromText 등.
  • 전문검색: MATCH(col) AGAINST ('+나주 +문학' IN BOOLEAN MODE)
    주의: InnoDB FULLTEXT는 한국어 형태소 한계가 있습니다. 필요한 경우 외부 검색엔진(Elasticsearch 등) 고려.

12) 실전 예시: 하루 주간 매출 요약

-- 스키마: sales(id, sold_at DATETIME, amount DECIMAL(10,2))
-- 1) 오늘 vs 어제 매출
SELECT
  DATE(sold_at) AS d,
  ROUND(SUM(amount),0) AS total
FROM sales
WHERE sold_at >= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
GROUP BY d;

-- 2) 최근 7일 이동평균(윈도 함수)
SELECT
  DATE(sold_at) AS d,
  SUM(amount) AS day_sum,
  ROUND(AVG(SUM(amount)) OVER (ORDER BY DATE(sold_at)
       ROWS BETWEEN 6 PRECEDING AND CURRENT ROW), 0) AS ma7
FROM sales
GROUP BY DATE(sold_at)
ORDER BY d;

-- 3) 시간대별 피크(00~23시)
SELECT
  HOUR(sold_at) AS hh,
  SUM(amount) AS sum_amt
FROM sales
WHERE sold_at >= DATE_SUB(NOW(), INTERVAL 1 DAY)
GROUP BY hh
ORDER BY sum_amt DESC
LIMIT 5;

13) NULL·정밀도·성능 체크리스트

  • NULL: = NULL은 항상 FALSE → IS NULL/IS NOT NULL 사용.
  • 정밀도: 금액은 DECIMAL(p,s) 권장(부동소수 오차 회피).
  • 함수 + 인덱스: 8.0의 함수 기반 인덱스를 활용하면 계산식에서도 인덱스 사용 가능.
  • CREATE INDEX idx_date_only ON sales ((DATE(sold_at)));
  • 결정성(Deterministic): 가상 컬럼/함수 인덱스는 결정적 표현식이 유리합니다.
  • 로케일: 정렬/대소문자 비교는 COLLATE에 좌우. 한글 검색 품질은 적절한 Collation 선택.

14) 자주 쓰는 미니 레시피

-- 1) 안전 나누기(0 회피)
SELECT amount / NULLIF(cnt,0) FROM stats;

-- 2) 쉼표금액 표시
SELECT FORMAT(SUM(amount), 0) FROM sales;

-- 3) 전화번호 하이픈 제거/표준화
SELECT REGEXP_REPLACE(tel, '[^0-9]', '');

-- 4) 다중 문자열 포함 필터(INSTR/REGEXP)
SELECT * FROM posts
WHERE title REGEXP '(낭독극|오유권|영산포)';

-- 5) 문자열 → 날짜 캐스팅 실패 처리
SELECT STR_TO_DATE(dt_str, '%Y-%m-%d') AS d
FROM raw
WHERE STR_TO_DATE(dt_str, '%Y-%m-%d') IS NOT NULL;

15) 학습·강의용 실습 테이블

CREATE TABLE demo(
  id INT PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(50),
  score INT,
  jdoc JSON,
  sold_at DATETIME,
  amount DECIMAL(10,2)
);

INSERT INTO demo(name,score,jdoc,sold_at,amount) VALUES
('홍길동',95, JSON_OBJECT('city','나주','age',70), NOW(), 12000.00),
('심청',  82, JSON_OBJECT('city','영산포','age',68), NOW(),  8000.00),
('춘향', NULL, JSON_OBJECT('city','광주','age',72), NOW(),  9000.00);

-- 실습 포인트: COALESCE/CASE/JSON_EXTRACT/DATE_FORMAT/윈도함수
SELECT
  name,
  COALESCE(score,0) AS score0,
  JSON_UNQUOTE(JSON_EXTRACT(jdoc,'$.city')) AS city,
  DATE_FORMAT(sold_at, '%Y-%m-%d %H:%i') AS ts,
  SUM(amount) OVER (ORDER BY id) AS run_sum
FROM demo;

마무리 요약

  • 문자열/수치/날짜 핵심 함수로 **전처리·집계의 80%**를 해결할 수 있습니다.
  • 8.0의 윈도 함수·JSON 함수·함수 기반 인덱스는 보고서·API 성능을 크게 끌어올립니다.
  • 인덱스 활용을 위해 WHERE 절에서 컬럼을 함수로 감싸지 않기, 필요한 경우 생성 컬럼 + 인덱스를 고려하십시오.

 

반응형