6.

MySQL 関数完全リファレンス — 文字列・日付・集計

編集
この記事の要点
  • 文字列: CONCAT / SUBSTRING / REPLACE / LENGTH / LOWER / UPPER / TRIM
  • 数値: ROUND / FLOOR / CEILING / ABS / MOD / POW / SQRT
  • 日付: NOW / CURDATE / DATE_FORMAT / DATE_ADD / DATEDIFF / TIMESTAMPDIFF
  • 集計: COUNT / SUM / AVG / MAX / MIN / GROUP_CONCAT
  • 条件: IF / CASE WHEN / COALESCE / IFNULL / NULLIF
  • ウィンドウ関数 (8.0+): ROW_NUMBER / RANK / DENSE_RANK / LAG / LEAD

文字列関数

-- 連結
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: LENGTHCHAR_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 で拡張。

編集
Post Share
子ページ
  1. 現在日時の取得
  2. replaceによる文字列置換
同階層のページ
  1. ダウンロード&インストール方法(Windows)
  2. インストール方法(Linux)
  3. コマンド一覧
  4. SQL
  5. データ型
  6. 関数
  7. 管理ツール
  8. 設定
  9. パフォーマンスチューニング関連
  10. エクスポートおよびインポート
  11. エラー&トラブル
  12. 文字コードの確認
  13. 実行中の SQL の状態確認およびプロセスキルの方法
  14. パスワードの無効化設定
  15. root ユーザーの初期パスワード確認方法
  16. rootユーザーのパスワード変更方法
  17. LIMIT, OFFSET の始まりと挙動
  18. mysqlのバージョン確認方法
  19. MySQLで実行計画を表示する方法
  20. レプリケーションのステータス確認方法
  21. 中央値の導き方(バージョン8未満)
  22. 階層SQL(バージョン8未満)
  23. パーセンタイルの導き方
  24. 特定スキーマの全テーブルの全カラム情報を取得する方法

最近更新/作成されたページ