안내
본 문서는 블로그의 운영자인 본인이 Stackoverflow에 올린 답변을 정리한 글입니다.
Stackoverflow URL
http://stackoverflow.com/questions/20234035/mysql-make-a-excerpt-and-copy-it-to-another-column/20234349
SQLFiddle URL
http://www.sqlfiddle.com/#!2/c1031/1
질문
게시판의 본문 중 일부를 발췌하려고 한다. 본문에서 앞의 15개 문자는 제외한 뒤 그 위의 약 140개의 문자를 본문의 발췌로 사용하려고 한다. 단, 정확히 140개의 문자를 가져올 때 제일 마지막의 단어는중간에 잘리지 않고, 공백 단위의 단어에서 가져왔으면 좋겠다.
답변
질문자의 질문이 잘 이해되지 않을 수 있다. 도식화 해보면 다음과 같다.
약간은 복잡할 수 있지만 MySQL에서 문자열 연산을 통하여 할 수도 있다.
SELECT SUBSTRING(SUBSTRING(col, 16, 130), 1, IF(LENGTH(SUBSTRING(col, 16, 130)) - LENGTH(SUBSTRING_INDEX(SUBSTRING(col, 16, 130), ' ', -1)) = 0, LENGTH(SUBSTRING(col, 16, 130)), LENGTH(SUBSTRING(col, 16, 130)) - LENGTH(SUBSTRING_INDEX(SUBSTRING(col, 16, 130), ' ', -1)))) AS excerpt
FROM tab;
필자도 앞의 답변을 단 뒤 2달 뒤에 SQL문을 보니 이해가 잘 안 되었을 정도로 복잡한 SQL문이다.
모든 함수를 한번에 보니 어렵지만, 하나하나 분리해서 보면 이해가 될 것이다.
다음의 예는 앞의 SQL문이 어떻게 작동하는지 설명하고 있다. SQL이 너무 길어서 각 함수의 결과를 MySQL 변수에 저장했으며 발췌할 문자 또한 짧은 문자열로 변수에 저장해 두었다. 문제를 간단히 하기 위하여 앞의 15개 문자를 제거한 뒤, 남은 문자열에서 제일 마지막 단어를 자르는 예이다.
mysql> SET @str = '123456789012345ABC EDF';
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> SET @ltrim_len = 15;
Query OK, 0 rows affected (0.00 sec)
mysql> SET @ltrimmed_str = SUBSTRING(@str, @ltrim_len);
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> SET @right_word_warp = SUBSTRING_INDEX(@ltrimmed_str, ' ', -1);
Query OK, 0 rows affected (0.00 sec)
“MySQL” 카테고리의 추천 글
- MySQL IN subquery 성능. IN sub query는 가급적 사용을 피하자
- MySQL의 IN() v.s. EXISTS v.s. INNER JOIN 성능 비교
- MySQL INNER JOIN v.s EXISTS 성능 비교
- JOIN에서 중복된 레코드 제거하기
- MySQL 중복 레코드 관리 방법 - INSERT IGNORE, REPLACE INTO, ON DUPLICATE UPDATE
- MySQL GROUP BY 성능 최적화를 위한 INDEX 설계
- MySQL Query Cache를 빠르게 비우기
- MySQL Plugin에 대한 간단한 소개
- MySQL InnoDB Index Statistics
- MySQL Foreign key 사용 시 주의 사항 (Can’t create table (errno: 150))