タイトル: 関数
SEOタイトル: MySQL 関数完全リファレンス — 文字列・日付・集計
| この記事の要点 |
|
文字列関数
-- 連結
SELECT CONCAT('Hello, ', name, '!') FROM users;
SELECT CONCAT_WS('-', '2024', '01', '15'); -- '2024-01-15' (区切り付き)
-- 部分文字列 (1 始まり)
SELECT SUBSTRING('hello world', 7, 5); -- 'world'
SELECT SUBSTRING_INDEX('a,b,c,d', ',', 2); -- 'a,b'
-- 置換
SELECT REPLACE('foo bar foo', 'foo', 'baz'); -- 'baz bar baz'
-- 長さ (バイト)
SELECT LENGTH('あいう'); -- 9 (UTF-8 で 3 バイト × 3)
SELECT CHAR_LENGTH('あいう'); -- 3 (文字数)
-- 大小変換
SELECT LOWER('Hello'), UPPER('Hello');
-- 空白除去
SELECT TRIM(' hello '), LTRIM(' hello'), RTRIM('hello ');
SELECT TRIM(BOTH '0' FROM '00abc00'); -- 'abc'
-- パディング
SELECT LPAD('5', 3, '0'); -- '005'
SELECT RPAD('5', 3, '0'); -- '500'
-- 位置検索
SELECT INSTR('hello world', 'world'); -- 7
SELECT LOCATE('o', 'hello', 5); -- 5 (5 文字目から検索)
数値関数
-- 四捨五入
SELECT ROUND(3.7); -- 4
SELECT ROUND(3.14159, 2); -- 3.14
-- 切り捨て・切り上げ
SELECT FLOOR(3.7); -- 3
SELECT CEILING(3.2); -- 4
SELECT TRUNCATE(3.789, 1); -- 3.7 (切り捨て桁指定)
-- 絶対値・剰余
SELECT ABS(-5); -- 5
SELECT MOD(10, 3); -- 1
SELECT 10 % 3; -- 1 (同じ)
-- 累乗・平方根
SELECT POW(2, 10); -- 1024
SELECT SQRT(16); -- 4
-- 乱数
SELECT RAND(); -- 0〜1
SELECT FLOOR(RAND() * 100); -- 0〜99
日付・時刻関数
-- 現在時刻
SELECT NOW(); -- '2026-06-10 12:34:56'
SELECT CURDATE(); -- '2026-06-10'
SELECT CURTIME(); -- '12:34:56'
SELECT UNIX_TIMESTAMP(); -- 1749553496
-- フォーマット
SELECT DATE_FORMAT(NOW(), '%Y/%m/%d %H:%i'); -- '2026/06/10 12:34'
SELECT DATE_FORMAT(NOW(), '%Y年%m月%d日');
-- パース
SELECT STR_TO_DATE('2026/06/10', '%Y/%m/%d');
-- 加減算
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY); -- 7 日後
SELECT DATE_SUB(NOW(), INTERVAL 1 MONTH); -- 1 ヶ月前
SELECT NOW() + INTERVAL 1 HOUR; -- 1 時間後
-- 差分
SELECT DATEDIFF('2026-06-10', '2026-01-01'); -- 160 (日数)
SELECT TIMESTAMPDIFF(MONTH, '2025-01-01', '2026-06-10'); -- 17 (月数)
SELECT TIMESTAMPDIFF(YEAR, '1990-04-15', CURDATE()); -- 年齢計算
-- 抜き出し
SELECT YEAR(NOW()), MONTH(NOW()), DAY(NOW());
SELECT DAYOFWEEK(NOW()); -- 1=日, 2=月, ..., 7=土
SELECT DAYNAME(NOW()); -- 'Wednesday'
-- 月末
SELECT LAST_DAY(NOW());
DATE_FORMAT のフォーマット
| 記号 | 意味 | 例 |
|---|---|---|
| %Y | 年 4 桁 | 2026 |
| %y | 年 2 桁 | 26 |
| %m | 月 (01-12) | 06 |
| %c | 月 (1-12) | 6 |
| %d | 日 (01-31) | 10 |
| %e | 日 (1-31) | 10 |
| %H | 時 (00-23) | 14 |
| %h / %I | 時 (01-12) | 02 |
| %i | 分 (00-59) | 30 |
| %s | 秒 (00-59) | 45 |
| %W | 曜日名 | Wednesday |
| %a | 曜日略 | Wed |
集計関数
SELECT
COUNT(*), -- 全件
COUNT(email), -- email が NULL 以外の件数
COUNT(DISTINCT user_id),
SUM(amount),
AVG(amount),
MAX(created_at),
MIN(price),
GROUP_CONCAT(name SEPARATOR ', ') -- 文字列連結 (デフォルト 1024 文字)
FROM orders
WHERE status = 'paid';
-- GROUP BY と合わせて
SELECT user_id, COUNT(*) AS cnt, SUM(amount) AS total
FROM orders
GROUP BY user_id
HAVING total > 10000;
条件関数
-- IF (式, 真の値, 偽の値)
SELECT IF(score >= 60, '合格', '不合格') FROM students;
-- CASE WHEN
SELECT name,
CASE
WHEN score >= 90 THEN 'A'
WHEN score >= 80 THEN 'B'
WHEN score >= 60 THEN 'C'
ELSE 'F'
END AS grade
FROM students;
-- NULL ハンドリング
SELECT COALESCE(nickname, name, 'no name') FROM users;
-- 最初の非 NULL を返す
SELECT IFNULL(phone, 'none') FROM users;
-- 1 つだけ。NULL なら 'none'
SELECT NULLIF(a, b); -- a = b なら NULL、違えば a
ウィンドウ関数 (MySQL 8.0+)
-- ユーザー別売上ランキング
SELECT
user_id,
order_no,
amount,
ROW_NUMBER() OVER (PARTITION BY user_id ORDER BY amount DESC) AS rn,
RANK() OVER (PARTITION BY user_id ORDER BY amount DESC) AS rk,
DENSE_RANK() OVER (PARTITION BY user_id ORDER BY amount DESC) AS drk
FROM orders;
-- 前後の行
SELECT
date,
sales,
LAG(sales, 1) OVER (ORDER BY date) AS prev_sales,
LEAD(sales, 1) OVER (ORDER BY date) AS next_sales,
sales - LAG(sales, 1) OVER (ORDER BY date) AS diff
FROM daily_sales;
-- 移動平均
SELECT date, sales,
AVG(sales) OVER (
ORDER BY date
ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
) AS ma_7days
FROM daily_sales;
JSON 関数 (5.7+)
-- 値取り出し
SELECT JSON_EXTRACT(meta, '$.theme') FROM user_settings;
SELECT meta->>'$.theme' FROM user_settings; -- 同じ (8.0+)
-- 更新
UPDATE user_settings
SET meta = JSON_SET(meta, '$.theme', 'dark')
WHERE user_id = 1;
-- キー存在
SELECT * FROM user_settings WHERE JSON_CONTAINS_PATH(meta, 'one', '$.theme');
-- 配列に追加
UPDATE user_tags SET tags = JSON_ARRAY_APPEND(tags, '$', 'new');
FAQ
Q: LENGTH と CHAR_LENGTH の違い
A: LENGTH はバイト数、CHAR_LENGTH は文字数。UTF-8 で日本語は 3 バイト、絵文字は 4 バイト。
Q: NOW() と CURRENT_TIMESTAMP の違い
A: 同じ。エイリアス関係。
Q: GROUP_CONCAT が途中で切れる
A: group_concat_max_len が 1024 バイト。SET SESSION group_concat_max_len = 1000000 で拡張。