ぱんだツールズぱんだツールズ

SQL方言 横断検索

MySQL / PostgreSQL / SQLite / SQL Server のSQL構文を横断比較

ぱんだツールズファイルはサーバーに送信されません
MySQL: 57PostgreSQL: 59SQLite: 52SQL Server: 58
最終更新: 2026-04-13
全59件を表示中
整数型基本
データ型
MySQL
INT / BIGINT

4バイト整数 / 8バイト整数

* TINYINT, SMALLINT, MEDIUMINT もあり

PostgreSQL
INTEGER / BIGINT

4バイト整数 / 8バイト整数

* SMALLINT(2バイト) もあり。INT は INTEGER のエイリアス

SQLite
INTEGER

可変長整数(1〜8バイト)

* SQLite は動的型付け。格納値に応じてサイズが変動

SQL Server
INT / BIGINT

4バイト整数 / 8バイト整数

* TINYINT(1バイト), SMALLINT(2バイト) もあり

比較メモ: SQLite の INTEGER は格納する値に応じて1〜8バイトに自動調整される。他のDBは固定サイズ

文字列型(可変長)基本
データ型
MySQL
VARCHAR(n)

最大 n 文字の可変長文字列

* 最大 65,535 バイト。文字コードにより格納可能文字数が変わる

PostgreSQL
VARCHAR(n) / TEXT

VARCHAR(n) は最大 n 文字。TEXT は無制限

* VARCHAR と TEXT のパフォーマンス差はほぼなし

SQLite
TEXT

すべての文字列は TEXT 型

* VARCHAR(n) と書いても内部的には TEXT として扱われる

SQL Server
VARCHAR(n) / NVARCHAR(n)

VARCHAR は非Unicode、NVARCHAR はUnicode対応

* NVARCHAR(MAX) で最大約2GB。日本語には NVARCHAR を推奨

比較メモ: SQL Server で日本語を扱う場合は NVARCHAR を使用する。MySQL・PostgreSQL はデフォルトで Unicode 対応

文字列型(固定長)基本
データ型
MySQL
CHAR(n)

固定長 n 文字。空白で右パディング

* 最大 255 文字

PostgreSQL
CHAR(n)

固定長 n 文字。空白で右パディング

* 実用上は VARCHAR/TEXT を推奨

SQLite
TEXT

固定長型なし。TEXT として扱われる

* CHAR(n) と書いても TEXT になる

SQL Server
CHAR(n) / NCHAR(n)

CHAR は非Unicode固定長、NCHAR はUnicode固定長

* 最大 8,000 バイト(CHAR) / 4,000 文字(NCHAR)

比較メモ: SQLite には固定長文字列型がなく、すべて TEXT 扱い。固定長が必要なコード値にはCHECK制約で長さを担保

テキスト型(大容量)基本
データ型
MySQL
TEXT / MEDIUMTEXT / LONGTEXT

TEXT(64KB), MEDIUMTEXT(16MB), LONGTEXT(4GB)

* サイズに応じて使い分ける

PostgreSQL
TEXT

無制限のテキスト型

* VARCHAR と TEXT にパフォーマンス差なし

SQLite
TEXT

最大約1GBのテキスト

* SQLITE_MAX_LENGTH で制限変更可能

SQL Server
VARCHAR(MAX) / NVARCHAR(MAX)

最大約2GBのテキスト

* TEXT/NTEXT は非推奨。VARCHAR(MAX) を使用

比較メモ: SQL Server の TEXT/NTEXT 型は非推奨。VARCHAR(MAX)/NVARCHAR(MAX) に移行が推奨されている

真偽値型基本
データ型
MySQL
BOOLEAN / TINYINT(1)

BOOLEAN は TINYINT(1) のエイリアス

* TRUE=1, FALSE=0 として格納

PostgreSQL
BOOLEAN

真の論理型(true/false/null)

* true, false, 't', 'f', 'yes', 'no', '1', '0' を受け付ける

SQLite
INTEGER (0 or 1)

専用のBOOLEAN型なし

* BOOLEAN と書いても INTEGER(数値親和性)として扱われる

SQL Server
BIT

0 または 1 を格納

* NULL も許容。TRUE/FALSE リテラルは使用不可

比較メモ: PostgreSQL だけが真のBOOLEAN型を持つ。MySQL は TINYINT(1)、SQLite は INTEGER、SQL Server は BIT で代替

日付型基本
データ型
MySQL
DATE

日付のみ(YYYY-MM-DD)

* 範囲: 1000-01-01 〜 9999-12-31

PostgreSQL
DATE

日付のみ(YYYY-MM-DD)

* 範囲: 4713 BC 〜 5874897 AD

SQLite
TEXT / REAL / INTEGER

専用の日付型なし

* TEXT('YYYY-MM-DD'), REAL(ユリウス日), INTEGER(Unix時間) で代替

SQL Server
DATE

日付のみ(YYYY-MM-DD)

* 範囲: 0001-01-01 〜 9999-12-31。SQL Server 2008 以降

比較メモ: SQLite には日付型がなく、TEXT・REAL・INTEGER のいずれかで日付を格納する。日付関数で操作可能

日時型基本
データ型
MySQL
DATETIME / TIMESTAMP

DATETIME はタイムゾーンなし。TIMESTAMP は UTC で格納

* TIMESTAMP は 2038-01-19 まで。DATETIME は 9999-12-31 まで

PostgreSQL
TIMESTAMP / TIMESTAMPTZ

TIMESTAMP はタイムゾーンなし。TIMESTAMPTZ はタイムゾーン付き

* TIMESTAMPTZ は入力時にUTCに変換して格納

SQLite
TEXT / REAL / INTEGER

専用の日時型なし

* TEXT('YYYY-MM-DD HH:MM:SS'), REAL(ユリウス日), INTEGER(Unix時間)

SQL Server
DATETIME2 / DATETIMEOFFSET

DATETIME2 はTZなし。DATETIMEOFFSET はTZ付き

* DATETIME(旧)は精度が低い。DATETIME2 を推奨

比較メモ: タイムゾーン付き: PostgreSQL=TIMESTAMPTZ, MySQL=TIMESTAMP(UTC変換), SQL Server=DATETIMEOFFSET

JSON型中級
データ型
MySQL
JSON

JSON形式で格納・検証あり

* 5.7以降。->>, ->演算子でアクセス。インデックスは仮想列経由

PostgreSQL
JSON / JSONB

JSON はテキスト格納、JSONB はバイナリ格納

* JSONB 推奨。GINインデックス対応、演算子豊富(->>, @>, ? 等)

SQLite
TEXT + json関数

専用型なし。TEXT に格納し json() 関数で操作

* 3.38.0 以降で -> / ->> 演算子に対応

SQL Server
NVARCHAR(MAX) + JSON関数

専用型なし。NVARCHAR に格納

* OPENJSON, JSON_VALUE, JSON_QUERY 等で操作。2016 以降

比較メモ: PostgreSQL の JSONB が最も機能豊富(GINインデックス、包含演算子等)。MySQL も JSON 型をネイティブサポート。SQLite/SQL Server はテキスト格納+関数

UUID型中級
データ型
MySQL
CHAR(36) / BINARY(16)

専用型なし。文字列またはバイナリで格納

* 8.0 以降は UUID_TO_BIN() / BIN_TO_UUID() 関数あり

PostgreSQL
UUID

ネイティブUUID型

* gen_random_uuid() で生成(14以降は組込み。以前は pgcrypto 拡張)

SQLite
TEXT / BLOB

専用型なし。TEXT(36文字)またはBLOBで格納

* UUID生成関数なし。アプリケーション側で生成

SQL Server
UNIQUEIDENTIFIER

ネイティブGUID型

* NEWID() / NEWSEQUENTIALID() で生成

比較メモ: PostgreSQL と SQL Server はネイティブの UUID/GUID 型を持つ。MySQL と SQLite は文字列/バイナリで代替

BLOB / バイナリ型中級
データ型
MySQL
BLOB / MEDIUMBLOB / LONGBLOB

BLOB(64KB), MEDIUMBLOB(16MB), LONGBLOB(4GB)

* BINARY(n) / VARBINARY(n) もあり

PostgreSQL
BYTEA

バイト配列型

* エスケープ形式またはhex形式で入出力。最大1GB

SQLite
BLOB

バイナリデータ型

* X'DEADBEEF' 形式のリテラル。最大サイズは SQLITE_MAX_LENGTH

SQL Server
VARBINARY(MAX)

最大約2GBのバイナリ

* IMAGE 型は非推奨。VARBINARY(MAX) を使用

比較メモ: PostgreSQL は BYTEA、SQL Server は VARBINARY(MAX) が標準。命名規則がDB毎に異なる

テーブル作成基本
DDL(テーブル操作)
MySQL
CREATE TABLE t (
  id INT PRIMARY KEY,
  name VARCHAR(100)
)

テーブルを作成

* ENGINE=InnoDB でストレージエンジン指定可

PostgreSQL
CREATE TABLE t (
  id INTEGER PRIMARY KEY,
  name VARCHAR(100)
)

テーブルを作成

* スキーマ指定: CREATE TABLE schema.t (...)

SQLite
CREATE TABLE t (
  id INTEGER PRIMARY KEY,
  name TEXT
)

テーブルを作成

* INTEGER PRIMARY KEY は自動で ROWID のエイリアスになる

SQL Server
CREATE TABLE t (
  id INT PRIMARY KEY,
  name NVARCHAR(100)
)

テーブルを作成

* スキーマ指定: CREATE TABLE dbo.t (...)

テーブル作成(IF NOT EXISTS)基本
DDL(テーブル操作)
MySQL
CREATE TABLE IF NOT EXISTS t (...)

テーブルが存在しない場合のみ作成

PostgreSQL
CREATE TABLE IF NOT EXISTS t (...)

テーブルが存在しない場合のみ作成

SQLite
CREATE TABLE IF NOT EXISTS t (...)

テーブルが存在しない場合のみ作成

SQL Server
IF NOT EXISTS (
  SELECT * FROM sys.tables
  WHERE name = 't'
)
CREATE TABLE t (...)

sys.tables を参照して存在確認

* CREATE TABLE IF NOT EXISTS 構文は非対応

比較メモ: SQL Server は IF NOT EXISTS 構文に非対応。sys.tables やOBJECT_ID() で存在確認が必要

テーブル削除(IF EXISTS)基本
DDL(テーブル操作)
MySQL
DROP TABLE IF EXISTS t

テーブルが存在する場合のみ削除

PostgreSQL
DROP TABLE IF EXISTS t

テーブルが存在する場合のみ削除

* CASCADE でFKの依存も同時に削除可

SQLite
DROP TABLE IF EXISTS t

テーブルが存在する場合のみ削除

SQL Server
DROP TABLE IF EXISTS t

テーブルが存在する場合のみ削除

* SQL Server 2016 以降で対応

比較メモ: SQL Server は 2016 以降で DROP TABLE IF EXISTS に対応。それ以前は IF OBJECT_ID() IS NOT NULL で判定

カラム追加基本
DDL(テーブル操作)
MySQL
ALTER TABLE t
  ADD COLUMN col VARCHAR(100)

カラムを追加

* AFTER col2 で位置指定可

PostgreSQL
ALTER TABLE t
  ADD COLUMN col VARCHAR(100)

カラムを追加

* IF NOT EXISTS も可(9.6以降)

SQLite
ALTER TABLE t
  ADD COLUMN col TEXT

カラムを追加

* デフォルト値は定数のみ(関数不可)

SQL Server
ALTER TABLE t
  ADD col NVARCHAR(100)

カラムを追加

* COLUMN キーワードは省略する

比較メモ: SQL Server では ADD COLUMN ではなく ADD col_name で記述。MySQL は AFTER で追加位置を指定可能

カラム名変更中級
DDL(テーブル操作)
MySQL
ALTER TABLE t
  RENAME COLUMN old TO new

カラム名を変更

* 8.0 以降。以前は CHANGE old new TYPE で型も再指定

PostgreSQL
ALTER TABLE t
  RENAME COLUMN old TO new

カラム名を変更

SQLite
ALTER TABLE t
  RENAME COLUMN old TO new

カラム名を変更

* 3.25.0 以降で対応

SQL Server
EXEC sp_rename
  't.old', 'new', 'COLUMN'

sp_rename ストアドプロシージャでカラム名変更

* ALTER TABLE RENAME COLUMN は非対応

比較メモ: SQL Server のみ sp_rename プロシージャを使用。他の3つのDBは ALTER TABLE RENAME COLUMN で統一

カラムの型変更中級
DDL(テーブル操作)
MySQL
ALTER TABLE t
  MODIFY COLUMN col BIGINT

MODIFY COLUMN で型を変更

* CHANGE col col BIGINT でも可

PostgreSQL
ALTER TABLE t
  ALTER COLUMN col TYPE BIGINT

ALTER COLUMN ... TYPE で型を変更

* USING col::bigint で変換式を指定可

SQLite

直接対応する構文なし

ALTER TABLE での型変更は不可。テーブル再作成が必要

SQL Server
ALTER TABLE t
  ALTER COLUMN col BIGINT

ALTER COLUMN で型を変更

比較メモ: SQLite はカラムの型変更に非対応。新テーブル作成→データ移行→リネームの手順が必要

テーブル名変更基本
DDL(テーブル操作)
MySQL
RENAME TABLE old TO new

テーブル名を変更

* ALTER TABLE old RENAME TO new でも可

PostgreSQL
ALTER TABLE old RENAME TO new

テーブル名を変更

SQLite
ALTER TABLE old RENAME TO new

テーブル名を変更

SQL Server
EXEC sp_rename 'old', 'new'

sp_rename でテーブル名を変更

比較メモ: MySQL は RENAME TABLE 構文がある。PostgreSQL/SQLite は ALTER TABLE RENAME TO。SQL Server は sp_rename

AUTO INCREMENT / SERIAL基本
DDL(テーブル操作)
MySQL
id INT AUTO_INCREMENT PRIMARY KEY

AUTO_INCREMENT で自動採番

* テーブルごとに1つのみ。ALTER TABLE t AUTO_INCREMENT = 100 で初期値変更

PostgreSQL
id SERIAL PRIMARY KEY
-- または
id INT GENERATED ALWAYS AS IDENTITY

SERIAL はシーケンスを自動作成。IDENTITY は SQL標準(10以降)

* SERIAL は実質 CREATE SEQUENCE + DEFAULT の糖衣構文

SQLite
id INTEGER PRIMARY KEY AUTOINCREMENT

AUTOINCREMENT で厳密な連番を保証

* AUTOINCREMENT なしでも ROWID で自動採番(削除ID再利用あり)

SQL Server
id INT IDENTITY(1,1) PRIMARY KEY

IDENTITY(開始値, 増分) で自動採番

* IDENTITY_INSERT ON で手動挿入可

比較メモ: 構文はDB毎に大きく異なる: MySQL=AUTO_INCREMENT, PostgreSQL=SERIAL/IDENTITY, SQLite=AUTOINCREMENT, SQL Server=IDENTITY

UPSERT(INSERT or UPDATE)中級
DML(データ操作)
MySQL
INSERT INTO t (id, name)
VALUES (1, 'A')
ON DUPLICATE KEY UPDATE
  name = VALUES(name)

ON DUPLICATE KEY UPDATE で重複時に更新

* 8.0.19 以降は VALUES() の代わりに AS エイリアスも可

PostgreSQL
INSERT INTO t (id, name)
VALUES (1, 'A')
ON CONFLICT (id) DO UPDATE
  SET name = EXCLUDED.name

ON CONFLICT ... DO UPDATE で重複時に更新

* DO NOTHING で重複を無視も可能

SQLite
INSERT INTO t (id, name)
VALUES (1, 'A')
ON CONFLICT (id) DO UPDATE
  SET name = excluded.name

ON CONFLICT ... DO UPDATE で重複時に更新

* 3.24.0 以降で対応。PostgreSQL と類似構文

SQL Server
MERGE INTO t AS target
USING (VALUES (1, 'A'))
  AS src (id, name)
  ON target.id = src.id
WHEN MATCHED THEN
  UPDATE SET name = src.name
WHEN NOT MATCHED THEN
  INSERT (id, name)
  VALUES (src.id, src.name);

MERGE文で UPSERT を実現

* セミコロン必須。WHEN NOT MATCHED BY SOURCE で削除も可

比較メモ: MySQL は ON DUPLICATE KEY UPDATE、PostgreSQL/SQLite は ON CONFLICT、SQL Server は MERGE 文。構文が大きく異なる

LIMIT / OFFSET基本
DML(データ操作)
MySQL
SELECT * FROM t
LIMIT 10 OFFSET 20

LIMIT n OFFSET m で行数制限

* LIMIT 20, 10 の省略形もあり(第1引数がOFFSET)

PostgreSQL
SELECT * FROM t
LIMIT 10 OFFSET 20

LIMIT n OFFSET m で行数制限

* SQL標準の FETCH FIRST 10 ROWS ONLY も対応

SQLite
SELECT * FROM t
LIMIT 10 OFFSET 20

LIMIT n OFFSET m で行数制限

* LIMIT 10, 20 の形式にも対応

SQL Server
SELECT * FROM t
ORDER BY id
OFFSET 20 ROWS
FETCH NEXT 10 ROWS ONLY

OFFSET-FETCH 句で行数制限

* ORDER BY 必須。TOP n は OFFSET 不可(TOP 10 は先頭10件のみ)

比較メモ: MySQL/PostgreSQL/SQLite は LIMIT-OFFSET 構文。SQL Server は OFFSET-FETCH(ORDER BY 必須)または TOP n

文字列連結(||演算子)基本
DML(データ操作)
MySQL
SELECT CONCAT('Hello', ' ', 'World')

CONCAT() 関数で連結

* || は論理OR(sql_mode に PIPES_AS_CONCAT を設定すると || も使える)

PostgreSQL
SELECT 'Hello' || ' ' || 'World'

|| 演算子で連結

* CONCAT() 関数も使用可能。NULL は空文字扱い(CONCAT時)

SQLite
SELECT 'Hello' || ' ' || 'World'

|| 演算子で連結

* CONCAT() は 3.44.0 以降で対応

SQL Server
SELECT 'Hello' + ' ' + 'World'

+ 演算子で連結

* CONCAT() 関数も使用可能(2012以降)。NULL は空文字扱い(CONCAT時)

比較メモ: MySQL は CONCAT()、PostgreSQL/SQLite は ||、SQL Server は + が標準。CONCAT() 関数は全DBで使用可能

NULL合体(COALESCE / IFNULL / ISNULL)基本
DML(データ操作)
MySQL
SELECT COALESCE(col, '代替値')
-- または
SELECT IFNULL(col, '代替値')

COALESCE(複数引数可)/ IFNULL(2引数)

* IFNULL は MySQL 独自。COALESCE が推奨

PostgreSQL
SELECT COALESCE(col, '代替値')

COALESCE で最初の非NULL値を返す

* NULLIF(a, b) で a=b なら NULL を返す関数もあり

SQLite
SELECT COALESCE(col, '代替値')
-- または
SELECT IFNULL(col, '代替値')

COALESCE / IFNULL の両方に対応

SQL Server
SELECT COALESCE(col, '代替値')
-- または
SELECT ISNULL(col, '代替値')

COALESCE(複数引数可)/ ISNULL(2引数)

* ISNULL は SQL Server 独自。COALESCE が SQL標準

比較メモ: COALESCE は全DBで使用可能(SQL標準)。独自関数: MySQL=IFNULL, SQL Server=ISNULL, SQLite=IFNULL

CASE WHEN基本
DML(データ操作)
MySQL
SELECT CASE
  WHEN score >= 80 THEN 'A'
  WHEN score >= 60 THEN 'B'
  ELSE 'C'
END AS grade
FROM t

CASE WHEN で条件分岐

PostgreSQL
SELECT CASE
  WHEN score >= 80 THEN 'A'
  WHEN score >= 60 THEN 'B'
  ELSE 'C'
END AS grade
FROM t

CASE WHEN で条件分岐

SQLite
SELECT CASE
  WHEN score >= 80 THEN 'A'
  WHEN score >= 60 THEN 'B'
  ELSE 'C'
END AS grade
FROM t

CASE WHEN で条件分岐

SQL Server
SELECT CASE
  WHEN score >= 80 THEN 'A'
  WHEN score >= 60 THEN 'B'
  ELSE 'C'
END AS grade
FROM t

CASE WHEN で条件分岐

比較メモ: CASE WHEN 構文は SQL標準であり、4つのDB全てで同一の構文が使える

EXISTS / IN サブクエリ中級
DML(データ操作)
MySQL
SELECT * FROM t1
WHERE EXISTS (
  SELECT 1 FROM t2
  WHERE t2.id = t1.id
)

EXISTS / IN ともに使用可能

* EXISTS の方がパフォーマンスが良い場合が多い

PostgreSQL
SELECT * FROM t1
WHERE EXISTS (
  SELECT 1 FROM t2
  WHERE t2.id = t1.id
)

EXISTS / IN ともに使用可能

* オプティマイザが EXISTS/IN を自動的に最適化

SQLite
SELECT * FROM t1
WHERE EXISTS (
  SELECT 1 FROM t2
  WHERE t2.id = t1.id
)

EXISTS / IN ともに使用可能

SQL Server
SELECT * FROM t1
WHERE EXISTS (
  SELECT 1 FROM t2
  WHERE t2.id = t1.id
)

EXISTS / IN ともに使用可能

* オプティマイザが内部的に書き換えを行う

比較メモ: EXISTS/IN 構文は全DBで同一。大量データでは EXISTS が IN より効率的なことが多い

MERGE文応用
DML(データ操作)
MySQL

直接対応する構文なし

MERGE文は非対応。ON DUPLICATE KEY UPDATE または INSERT IGNORE で代替

PostgreSQL
MERGE INTO target t
USING source s ON t.id = s.id
WHEN MATCHED THEN
  UPDATE SET name = s.name
WHEN NOT MATCHED THEN
  INSERT (id, name)
  VALUES (s.id, s.name)

MERGE文でテーブル同期

* 15 以降で対応。それ以前は ON CONFLICT で代替

SQLite

直接対応する構文なし

MERGE文は非対応。ON CONFLICT で代替

SQL Server
MERGE INTO target AS t
USING source AS s ON t.id = s.id
WHEN MATCHED THEN
  UPDATE SET name = s.name
WHEN NOT MATCHED THEN
  INSERT (id, name)
  VALUES (s.id, s.name);

MERGE文でテーブル同期

* セミコロン必須。WHEN NOT MATCHED BY SOURCE も可

比較メモ: MERGE文は SQL Server が最も古くから対応。PostgreSQL は 15 で追加。MySQL/SQLite は非対応

ページネーション(カーソルベース)中級
DML(データ操作)
MySQL
SELECT * FROM t
WHERE id > :last_id
ORDER BY id
LIMIT 10

WHERE + LIMIT でカーソルベース

* OFFSET ベースより高速(大量データ時)

PostgreSQL
SELECT * FROM t
WHERE id > :last_id
ORDER BY id
LIMIT 10

WHERE + LIMIT でカーソルベース

* DECLARE CURSOR も使用可能(トランザクション内)

SQLite
SELECT * FROM t
WHERE id > :last_id
ORDER BY id
LIMIT 10

WHERE + LIMIT でカーソルベース

SQL Server
SELECT * FROM t
WHERE id > @last_id
ORDER BY id
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY

WHERE + FETCH NEXT でカーソルベース

* OFFSET 0 ROWS は省略不可

比較メモ: カーソルベースのページネーションはパフォーマンスが高い。SQL Server はパラメータに @ を使用

部分文字列取得基本
文字列関数
MySQL
SELECT SUBSTRING('Hello', 1, 3)
-- 結果: 'Hel'

SUBSTRING(str, pos, len)

* SUBSTR でも可。位置は 1 始まり

PostgreSQL
SELECT SUBSTRING('Hello', 1, 3)
-- 結果: 'Hel'

SUBSTRING(str FROM pos FOR len)

* SUBSTR(str, pos, len) でも可

SQLite
SELECT SUBSTR('Hello', 1, 3)
-- 結果: 'Hel'

SUBSTR(str, pos, len)

* SUBSTRING は 3.34.0 以降で対応

SQL Server
SELECT SUBSTRING('Hello', 1, 3)
-- 結果: 'Hel'

SUBSTRING(str, pos, len)

* 位置は 1 始まり

比較メモ: 全DBで SUBSTRING(str, pos, len) 形式が使える。SQLite は伝統的に SUBSTR を使用

文字列の長さ基本
文字列関数
MySQL
SELECT CHAR_LENGTH('こんにちは')
-- 結果: 5

CHAR_LENGTH() で文字数を返す

* LENGTH() はバイト数を返す(UTF-8で日本語は3倍)

PostgreSQL
SELECT LENGTH('こんにちは')
-- 結果: 5

LENGTH() で文字数を返す

* CHAR_LENGTH() も同じ結果。OCTET_LENGTH() でバイト数

SQLite
SELECT LENGTH('こんにちは')
-- 結果: 5

LENGTH() で文字数を返す

* BLOB の場合はバイト数を返す

SQL Server
SELECT LEN('こんにちは')
-- 結果: 5

LEN() で文字数を返す

* 末尾の空白を除外。DATALENGTH() でバイト数

比較メモ: MySQL は CHAR_LENGTH()=文字数、LENGTH()=バイト数。PostgreSQL/SQLite は LENGTH()=文字数。SQL Server は LEN()

大文字 / 小文字変換基本
文字列関数
MySQL
SELECT UPPER('hello'), LOWER('HELLO')

UPPER() / LOWER() で変換

PostgreSQL
SELECT UPPER('hello'), LOWER('HELLO')

UPPER() / LOWER() で変換

* INITCAP() で先頭大文字化も可

SQLite
SELECT UPPER('hello'), LOWER('HELLO')

UPPER() / LOWER() で変換

* ASCII文字のみ対応。Unicode文字の変換は ICU 拡張が必要

SQL Server
SELECT UPPER('hello'), LOWER('HELLO')

UPPER() / LOWER() で変換

比較メモ: UPPER/LOWER は全DBで共通。SQLite は標準ではASCII文字のみ対応(日本語の大文字小文字変換は不要)

文字列置換基本
文字列関数
MySQL
SELECT REPLACE('Hello World', 'World', 'SQL')
-- 結果: 'Hello SQL'

REPLACE(str, from, to) で置換

PostgreSQL
SELECT REPLACE('Hello World', 'World', 'SQL')
-- 結果: 'Hello SQL'

REPLACE(str, from, to) で置換

* OVERLAY() で位置指定の上書きも可

SQLite
SELECT REPLACE('Hello World', 'World', 'SQL')
-- 結果: 'Hello SQL'

REPLACE(str, from, to) で置換

SQL Server
SELECT REPLACE('Hello World', 'World', 'SQL')
-- 結果: 'Hello SQL'

REPLACE(str, from, to) で置換

比較メモ: REPLACE 関数は全DBで同一の構文・動作

文字列結合(GROUP_CONCAT / STRING_AGG)中級
文字列関数
MySQL
SELECT GROUP_CONCAT(name
  ORDER BY name
  SEPARATOR ', ')
FROM t

GROUP_CONCAT で文字列を結合

* デフォルト区切りはカンマ。最大長は group_concat_max_len

PostgreSQL
SELECT STRING_AGG(name, ', '
  ORDER BY name)
FROM t

STRING_AGG で文字列を結合

* ARRAY_AGG で配列として取得も可

SQLite
SELECT GROUP_CONCAT(name, ', ')
FROM t

GROUP_CONCAT で文字列を結合

* ORDER BY は GROUP_CONCAT 内では指定不可

SQL Server
SELECT STRING_AGG(name, ', ')
  WITHIN GROUP (ORDER BY name)
FROM t

STRING_AGG で文字列を結合

* 2017 以降。以前は FOR XML PATH で代替

比較メモ: MySQL/SQLite は GROUP_CONCAT、PostgreSQL/SQL Server は STRING_AGG。関数名と構文が異なる

トリム(前後の空白除去)基本
文字列関数
MySQL
SELECT TRIM('  hello  ')
-- 結果: 'hello'

TRIM() で前後の空白を除去

* TRIM(BOTH/LEADING/TRAILING x FROM str) で指定文字の除去可

PostgreSQL
SELECT TRIM('  hello  ')
-- 結果: 'hello'

TRIM() で前後の空白を除去

* BTRIM('xxhelloxx', 'x') で指定文字除去

SQLite
SELECT TRIM('  hello  ')
-- 結果: 'hello'

TRIM() で前後の空白を除去

* LTRIM / RTRIM で左右個別に除去可

SQL Server
SELECT TRIM('  hello  ')
-- 結果: 'hello'

TRIM() で前後の空白を除去

* 2017 以降。以前は LTRIM(RTRIM(str)) で代替

比較メモ: TRIM 関数は全DBで使用可能。SQL Server の TRIM は 2017 以降で追加

正規表現マッチ中級
文字列関数
MySQL
SELECT * FROM t
WHERE name REGEXP '^[A-Z]'

REGEXP / RLIKE で正規表現マッチ

* 8.0 以降は ICU 正規表現。REGEXP_LIKE() 関数もあり

PostgreSQL
SELECT * FROM t
WHERE name ~ '^[A-Z]'

~ 演算子で正規表現マッチ

* ~* で大文字小文字を無視。SIMILAR TO (SQL標準) も使用可

SQLite

直接対応する構文なし

REGEXP は標準では未実装。アプリ側で regexp() 関数を登録すれば使用可

SQL Server
SELECT * FROM t
WHERE name LIKE '[A-Z]%'

LIKE のパターンで部分的に対応

* フル正規表現は CLR 関数経由。LIKE は % _ [] のみ

比較メモ: MySQL は REGEXP、PostgreSQL は ~。SQLite は標準非対応。SQL Server は LIKE の簡易パターンのみ

文字列の位置検索中級
文字列関数
MySQL
SELECT LOCATE('World', 'Hello World')
-- 結果: 7

LOCATE(substr, str) で位置を返す

* INSTR(str, substr) も可(引数順が逆)

PostgreSQL
SELECT POSITION('World' IN 'Hello World')
-- 結果: 7

POSITION(substr IN str) で位置を返す

* STRPOS(str, substr) も可

SQLite
SELECT INSTR('Hello World', 'World')
-- 結果: 7

INSTR(str, substr) で位置を返す

SQL Server
SELECT CHARINDEX('World', 'Hello World')
-- 結果: 7

CHARINDEX(substr, str) で位置を返す

* 第3引数で検索開始位置を指定可

比較メモ: 関数名がDB毎に異なる: MySQL=LOCATE, PostgreSQL=POSITION, SQLite=INSTR, SQL Server=CHARINDEX

現在日時の取得基本
日付・時刻関数
MySQL
SELECT NOW()
-- 例: 2026-04-13 12:34:56

NOW() で現在日時を取得

* CURRENT_TIMESTAMP も同じ。UTC は UTC_TIMESTAMP()

PostgreSQL
SELECT NOW()
-- 例: 2026-04-13 12:34:56.123456+09

NOW() で現在日時(タイムゾーン付き)を取得

* CURRENT_TIMESTAMP も同じ。clock_timestamp() はステートメント内で変動

SQLite
SELECT datetime('now', 'localtime')
-- 例: 2026-04-13 12:34:56

datetime() 関数でフォーマット指定

* 'now' でUTC。'localtime' 修飾子でローカル時間

SQL Server
SELECT GETDATE()
-- 例: 2026-04-13 12:34:56.123

GETDATE() で現在日時を取得

* SYSDATETIME() でナノ秒精度。GETUTCDATE() でUTC

比較メモ: MySQL/PostgreSQL は NOW()、SQLite は datetime("now")、SQL Server は GETDATE()。CURRENT_TIMESTAMP は全DBで使用可

日付の差分計算中級
日付・時刻関数
MySQL
SELECT DATEDIFF('2026-04-13', '2026-01-01')
-- 結果: 102

DATEDIFF(date1, date2) で日数差

* TIMESTAMPDIFF(MONTH, d1, d2) で月数差も可

PostgreSQL
SELECT '2026-04-13'::date - '2026-01-01'::date
-- 結果: 102

date 型の減算で日数差を取得

* AGE('2026-04-13', '2026-01-01') で interval 形式も可

SQLite
SELECT julianday('2026-04-13')
  - julianday('2026-01-01')
-- 結果: 102.0

julianday() の差分で日数を計算

* 結果は浮動小数点。CAST(... AS INTEGER) で整数化

SQL Server
SELECT DATEDIFF(DAY, '2026-01-01', '2026-04-13')
-- 結果: 102

DATEDIFF(datepart, start, end) で差分

* datepart: YEAR, MONTH, DAY, HOUR 等を指定

比較メモ: MySQL と SQL Server は DATEDIFF だが引数順と形式が異なる。PostgreSQL は演算子、SQLite は julianday 関数

日付の加算中級
日付・時刻関数
MySQL
SELECT DATE_ADD('2026-04-13',
  INTERVAL 7 DAY)
-- 結果: 2026-04-20

DATE_ADD() + INTERVAL で加算

* '2026-04-13' + INTERVAL 7 DAY の演算子形式も可

PostgreSQL
SELECT '2026-04-13'::date + INTERVAL '7 days'
-- 結果: 2026-04-20

date + INTERVAL で加算

* INTERVAL '1 month 2 days' のような複合指定も可

SQLite
SELECT date('2026-04-13', '+7 days')
-- 結果: 2026-04-20

date() の修飾子で加算

* '+1 month', '-3 hours' 等の修飾子を指定

SQL Server
SELECT DATEADD(DAY, 7, '2026-04-13')
-- 結果: 2026-04-20

DATEADD(datepart, number, date) で加算

* datepart: YEAR, MONTH, DAY, HOUR 等

比較メモ: MySQL は DATE_ADD + INTERVAL、PostgreSQL は + INTERVAL 演算子、SQLite は date() 修飾子、SQL Server は DATEADD 関数

日付のフォーマット中級
日付・時刻関数
MySQL
SELECT DATE_FORMAT(NOW(),
  '%Y/%m/%d %H:%i:%s')
-- 結果: 2026/04/13 12:34:56

DATE_FORMAT() で書式指定

* %Y=4桁年, %m=月, %d=日, %H=時, %i=分, %s=秒

PostgreSQL
SELECT TO_CHAR(NOW(),
  'YYYY/MM/DD HH24:MI:SS')
-- 結果: 2026/04/13 12:34:56

TO_CHAR() で書式指定

* YYYY=年, MM=月, DD=日, HH24=時, MI=分, SS=秒

SQLite
SELECT strftime('%Y/%m/%d %H:%M:%S',
  'now', 'localtime')
-- 結果: 2026/04/13 12:34:56

strftime() で書式指定

* %Y=年, %m=月, %d=日, %H=時, %M=分, %S=秒

SQL Server
SELECT FORMAT(GETDATE(),
  'yyyy/MM/dd HH:mm:ss')
-- 結果: 2026/04/13 12:34:56

FORMAT() で書式指定(2012以降)

* CONVERT(VARCHAR, GETDATE(), 111) でも可(定義済み書式)

比較メモ: 書式指定子がDB毎に異なる。MySQL=%Y, PostgreSQL=YYYY, SQLite=%Y, SQL Server=yyyy

年 / 月 / 日の抽出基本
日付・時刻関数
MySQL
SELECT YEAR(NOW()), MONTH(NOW()),
  DAY(NOW())

YEAR() / MONTH() / DAY() 関数

* EXTRACT(YEAR FROM date) も使用可

PostgreSQL
SELECT EXTRACT(YEAR FROM NOW()),
  EXTRACT(MONTH FROM NOW()),
  EXTRACT(DAY FROM NOW())

EXTRACT(field FROM date) で抽出

* date_part() 関数も同等

SQLite
SELECT strftime('%Y', 'now'),
  strftime('%m', 'now'),
  strftime('%d', 'now')

strftime() で個別に抽出

* 結果は文字列。整数が必要なら CAST

SQL Server
SELECT YEAR(GETDATE()),
  MONTH(GETDATE()),
  DAY(GETDATE())

YEAR() / MONTH() / DAY() 関数

* DATEPART(YEAR, date) も使用可

比較メモ: MySQL/SQL Server は YEAR()/MONTH()/DAY() 関数。PostgreSQL は EXTRACT。SQLite は strftime

タイムゾーン変換応用
日付・時刻関数
MySQL
SELECT CONVERT_TZ(NOW(),
  '+00:00', '+09:00')

CONVERT_TZ() でタイムゾーン変換

* mysql.time_zone_name テーブルのロードが必要な場合あり

PostgreSQL
SELECT NOW()
  AT TIME ZONE 'Asia/Tokyo'

AT TIME ZONE でタイムゾーン変換

* SET timezone = 'Asia/Tokyo' でセッション全体の設定も可

SQLite
SELECT datetime('now', 'localtime')

'localtime' 修飾子でUTC→ローカル変換

* 任意のタイムゾーンへの変換は不可。UTC とローカルのみ

SQL Server
SELECT GETDATE()
  AT TIME ZONE 'Tokyo Standard Time'

AT TIME ZONE でタイムゾーン変換

* 2016 以降。Windowsタイムゾーン名を使用

比較メモ: MySQL は CONVERT_TZ()、PostgreSQL/SQL Server は AT TIME ZONE。SQLite は UTC↔ローカルのみ対応

日付の切り捨て(TRUNC)中級
日付・時刻関数
MySQL
SELECT DATE_FORMAT('2026-04-13 15:30:00',
  '%Y-%m-01')
-- 結果: 2026-04-01

直接のTRUNC関数なし。DATE_FORMAT で代替

* DATE() で時刻を切り捨てて日付のみ取得可

PostgreSQL
SELECT DATE_TRUNC('month',
  '2026-04-13 15:30:00'::timestamp)
-- 結果: 2026-04-01 00:00:00

DATE_TRUNC(field, source) で切り捨て

* field: 'year', 'month', 'day', 'hour' 等

SQLite
SELECT date('2026-04-13', 'start of month')
-- 結果: 2026-04-01

'start of month' 修飾子で月初に切り捨て

* 'start of year', 'start of day' も可

SQL Server
SELECT DATETRUNC(MONTH,
  '2026-04-13 15:30:00')
-- 結果: 2026-04-01 00:00:00

DATETRUNC(datepart, date) で切り捨て

* 2022 以降。以前は DATEADD(MONTH, DATEDIFF(MONTH,0,date), 0)

比較メモ: PostgreSQL の DATE_TRUNC が最も直感的。MySQL は直接関数なし。SQL Server は 2022 で DATETRUNC を追加

GROUP BY + HAVING基本
集約関数
MySQL
SELECT category, COUNT(*)
FROM t
GROUP BY category
HAVING COUNT(*) > 5

GROUP BY + HAVING で条件付き集約

PostgreSQL
SELECT category, COUNT(*)
FROM t
GROUP BY category
HAVING COUNT(*) > 5

GROUP BY + HAVING で条件付き集約

SQLite
SELECT category, COUNT(*)
FROM t
GROUP BY category
HAVING COUNT(*) > 5

GROUP BY + HAVING で条件付き集約

SQL Server
SELECT category, COUNT(*)
FROM t
GROUP BY category
HAVING COUNT(*) > 5

GROUP BY + HAVING で条件付き集約

比較メモ: GROUP BY + HAVING は SQL標準であり、全DBで同一構文

ウィンドウ関数(ROW_NUMBER)中級
集約関数
MySQL
SELECT name, score,
  ROW_NUMBER() OVER (
    PARTITION BY dept
    ORDER BY score DESC
  ) AS rank
FROM t

ウィンドウ関数でランキング

* 8.0 以降で対応。RANK(), DENSE_RANK() もあり

PostgreSQL
SELECT name, score,
  ROW_NUMBER() OVER (
    PARTITION BY dept
    ORDER BY score DESC
  ) AS rank
FROM t

ウィンドウ関数でランキング

* RANK(), DENSE_RANK(), NTILE() 等も対応

SQLite
SELECT name, score,
  ROW_NUMBER() OVER (
    PARTITION BY dept
    ORDER BY score DESC
  ) AS rank
FROM t

ウィンドウ関数でランキング

* 3.25.0 以降で対応

SQL Server
SELECT name, score,
  ROW_NUMBER() OVER (
    PARTITION BY dept
    ORDER BY score DESC
  ) AS rank
FROM t

ウィンドウ関数でランキング

* 2005 以降で対応。最も早くから対応したDB

比較メモ: 構文は全DBで同一。対応時期: SQL Server 2005 → PostgreSQL 8.4 → SQLite 3.25 → MySQL 8.0

STRING_AGG / GROUP_CONCAT中級
集約関数
MySQL
SELECT dept,
  GROUP_CONCAT(name
    ORDER BY name
    SEPARATOR ', ')
FROM t
GROUP BY dept

GROUP_CONCAT で文字列を集約

PostgreSQL
SELECT dept,
  STRING_AGG(name, ', '
    ORDER BY name)
FROM t
GROUP BY dept

STRING_AGG で文字列を集約

SQLite
SELECT dept,
  GROUP_CONCAT(name, ', ')
FROM t
GROUP BY dept

GROUP_CONCAT で文字列を集約

* ORDER BY は指定不可

SQL Server
SELECT dept,
  STRING_AGG(name, ', ')
    WITHIN GROUP (
      ORDER BY name)
FROM t
GROUP BY dept

STRING_AGG で文字列を集約

* 2017 以降

比較メモ: MySQL/SQLite は GROUP_CONCAT、PostgreSQL/SQL Server は STRING_AGG。ソート指定の構文も異なる

DISTINCT ON(グループ内の最初の行)応用
集約関数
MySQL

直接対応する構文なし

DISTINCT ON は非対応。サブクエリ + ROW_NUMBER() で代替

PostgreSQL
SELECT DISTINCT ON (dept)
  dept, name, score
FROM t
ORDER BY dept, score DESC

DISTINCT ON で各グループの最初の行を取得

* ORDER BY の先頭カラムと DISTINCT ON のカラムを一致させる

SQLite

直接対応する構文なし

DISTINCT ON は非対応。GROUP BY + MAX/MIN または ROW_NUMBER() で代替

SQL Server

直接対応する構文なし

DISTINCT ON は非対応。ROW_NUMBER() + サブクエリで代替

比較メモ: DISTINCT ON は PostgreSQL 独自機能。他のDBではウィンドウ関数 ROW_NUMBER() で同等の結果を得る

四捨五入 / 切り捨て / 切り上げ基本
数値・数学関数
MySQL
SELECT ROUND(3.456, 2),
  FLOOR(3.7), CEIL(3.2)
-- 結果: 3.46, 3, 4

ROUND / FLOOR / CEIL で丸め処理

* TRUNCATE(n, d) で切り捨ても可

PostgreSQL
SELECT ROUND(3.456, 2),
  FLOOR(3.7), CEIL(3.2)
-- 結果: 3.46, 3, 4

ROUND / FLOOR / CEIL で丸め処理

* TRUNC(n, d) で切り捨ても可

SQLite
SELECT ROUND(3.456, 2),
  CAST(3.7 AS INTEGER)
-- 結果: 3.46, 3

ROUND で四捨五入

* FLOOR / CEIL は 3.35.0 以降で対応。以前は CAST で代替

SQL Server
SELECT ROUND(3.456, 2),
  FLOOR(3.7), CEILING(3.2)
-- 結果: 3.46, 3, 4

ROUND / FLOOR / CEILING で丸め処理

* CEILING(CEIL は不可)。ROUND(n, d, 1) で切り捨て

比較メモ: SQL Server は CEIL ではなく CEILING。SQLite は FLOOR/CEIL を 3.35.0 で追加

乱数生成基本
数値・数学関数
MySQL
SELECT RAND()
-- 結果: 0.0〜1.0の浮動小数点

RAND() で 0〜1 の乱数

* ORDER BY RAND() LIMIT 1 でランダム行取得

PostgreSQL
SELECT RANDOM()
-- 結果: 0.0〜1.0の浮動小数点

RANDOM() で 0〜1 の乱数

* SETSEED(n) でシード値を設定可能

SQLite
SELECT RANDOM()
-- 結果: -9223372036854775808〜9223372036854775807

RANDOM() で整数の乱数を返す

* 0〜1 の範囲にするには ABS(RANDOM()) % 100 / 100.0 等

SQL Server
SELECT RAND()
-- 結果: 0.0〜1.0の浮動小数点

RAND() で 0〜1 の乱数

* NEWID() でランダムソートも可

比較メモ: MySQL/SQL Server は RAND()、PostgreSQL は RANDOM()。SQLite の RANDOM() は整数を返す点に注意

絶対値 / 剰余基本
数値・数学関数
MySQL
SELECT ABS(-5), MOD(10, 3)
-- 結果: 5, 1

ABS() で絶対値、MOD() / % で剰余

* 10 % 3 の演算子形式も可

PostgreSQL
SELECT ABS(-5), MOD(10, 3)
-- 結果: 5, 1

ABS() で絶対値、MOD() / % で剰余

* 10 % 3 の演算子形式も可

SQLite
SELECT ABS(-5), 10 % 3
-- 結果: 5, 1

ABS() で絶対値、% 演算子で剰余

* MOD() 関数はなし

SQL Server
SELECT ABS(-5), 10 % 3
-- 結果: 5, 1

ABS() で絶対値、% 演算子で剰余

* MOD() 関数はなし

比較メモ: ABS は全DBで同一。MOD 関数は MySQL/PostgreSQL のみ。SQLite/SQL Server は % 演算子を使用

型変換(CAST)基本
数値・数学関数
MySQL
SELECT CAST('123' AS SIGNED),
  CAST(3.14 AS CHAR)

CAST(expr AS type) で型変換

* CONVERT(expr, type) も可。SIGNED/UNSIGNED は MySQL独自

PostgreSQL
SELECT CAST('123' AS INTEGER),
  '123'::INTEGER

CAST または :: 演算子で型変換

* :: はPostgreSQL独自の簡略構文

SQLite
SELECT CAST('123' AS INTEGER),
  CAST(3.14 AS TEXT)

CAST(expr AS type) で型変換

* 型親和性により暗黙変換も行われる

SQL Server
SELECT CAST('123' AS INT),
  CONVERT(INT, '123')

CAST / CONVERT で型変換

* CONVERT は第3引数で日付の書式スタイルを指定可

比較メモ: CAST は SQL標準で全DBで使用可能。PostgreSQL は :: 演算子、SQL Server は CONVERT が独自の代替手段

IF文 / CASE文(手続き型)中級
制御構文
MySQL
DELIMITER //
CREATE PROCEDURE test()
BEGIN
  IF @x > 0 THEN
    SELECT 'positive';
  ELSEIF @x = 0 THEN
    SELECT 'zero';
  ELSE
    SELECT 'negative';
  END IF;
END //

ストアドプロシージャ内で IF-ELSEIF-ELSE

* SELECT 文中では IF(条件, 真, 偽) 関数を使用

PostgreSQL
DO $$
BEGIN
  IF x > 0 THEN
    RAISE NOTICE 'positive';
  ELSIF x = 0 THEN
    RAISE NOTICE 'zero';
  ELSE
    RAISE NOTICE 'negative';
  END IF;
END $$;

PL/pgSQL の IF-ELSIF-ELSE

* ELSIF(ELSEIFではない)に注意

SQLite

直接対応する構文なし

手続き型 IF 文は非対応。CASE WHEN で代替

SQL Server
IF @x > 0
  PRINT 'positive'
ELSE IF @x = 0
  PRINT 'zero'
ELSE
  PRINT 'negative'

T-SQL の IF-ELSE IF-ELSE

* BEGIN...END でブロック化

比較メモ: キーワードが微妙に異なる: MySQL=ELSEIF, PostgreSQL=ELSIF, SQL Server=ELSE IF。SQLite は手続き型非対応

ストアドプロシージャ応用
制御構文
MySQL
DELIMITER //
CREATE PROCEDURE greet(
  IN name VARCHAR(100)
)
BEGIN
  SELECT CONCAT('Hello, ', name);
END //
DELIMITER ;

CALL greet('World');

CREATE PROCEDURE + CALL で実行

* IN/OUT/INOUT パラメータ。DELIMITER 変更が必要

PostgreSQL
CREATE OR REPLACE FUNCTION greet(
  name TEXT
) RETURNS TEXT AS $$
BEGIN
  RETURN 'Hello, ' || name;
END;
$$ LANGUAGE plpgsql;

SELECT greet('World');

CREATE FUNCTION で定義

* 11以降は CREATE PROCEDURE + CALL も可。以前は FUNCTION のみ

SQLite

直接対応する構文なし

ストアドプロシージャ機能なし。アプリケーション側で処理を実装

SQL Server
CREATE PROCEDURE greet
  @name NVARCHAR(100)
AS
BEGIN
  SELECT 'Hello, ' + @name;
END;
GO

EXEC greet 'World';

CREATE PROCEDURE + EXEC で実行

* @パラメータ名 でパラメータ定義。GO でバッチ区切り

比較メモ: SQLite はストアドプロシージャ非対応。PostgreSQL は伝統的に FUNCTION を使用(11以降 PROCEDURE も可)

変数宣言中級
制御構文
MySQL
SET @name = 'World';
SELECT @name;

-- プロシージャ内
DECLARE v_name VARCHAR(100)
  DEFAULT 'World';

ユーザー変数は @name、ローカル変数は DECLARE

* ユーザー変数はセッションスコープ

PostgreSQL
DO $$
DECLARE
  v_name TEXT := 'World';
BEGIN
  RAISE NOTICE '%', v_name;
END $$;

DECLARE ブロックで変数宣言

* PL/pgSQL 内でのみ使用可能。:= で代入

SQLite

直接対応する構文なし

変数宣言は非対応。WITH句(CTE)やサブクエリで代替

SQL Server
DECLARE @name NVARCHAR(100) = 'World';
SELECT @name;

-- SET で代入
SET @name = 'SQL Server';

DECLARE @変数名 型 で変数宣言

* SELECT @var = col FROM t で結果を変数に格納可

比較メモ: SQLite は変数機能なし。MySQL は @ユーザー変数が最もカジュアル。SQL Server も @変数で統一

一時テーブル中級
制御構文
MySQL
CREATE TEMPORARY TABLE tmp (
  id INT,
  name VARCHAR(100)
);

-- セッション終了時に自動削除

CREATE TEMPORARY TABLE で一時テーブル作成

PostgreSQL
CREATE TEMP TABLE tmp (
  id INTEGER,
  name TEXT
);

-- セッション終了時に自動削除

CREATE TEMP TABLE で一時テーブル作成

* ON COMMIT DROP / ON COMMIT DELETE ROWS も指定可

SQLite
CREATE TEMP TABLE tmp (
  id INTEGER,
  name TEXT
);

-- 接続終了時に自動削除

CREATE TEMP TABLE で一時テーブル作成

* 一時テーブルは temp スキーマに格納される

SQL Server
CREATE TABLE #tmp (
  id INT,
  name NVARCHAR(100)
);

-- セッション終了時に自動削除
-- ##tmp はグローバル一時テーブル

#テーブル名 でローカル一時テーブル

* ##テーブル名 でグローバル一時テーブル(全セッション共有)

比較メモ: MySQL/PostgreSQL/SQLite は CREATE TEMP TABLE。SQL Server は #プレフィックスで一時テーブルを表現する独自構文

インデックス作成中級
インデックス
MySQL
CREATE INDEX idx_name
  ON t (name)

CREATE INDEX で B-tree インデックス作成

* USING BTREE / HASH でインデックスタイプ指定可

PostgreSQL
CREATE INDEX idx_name
  ON t (name)

CREATE INDEX で B-tree インデックス作成

* USING btree / hash / gin / gist 等を指定可

SQLite
CREATE INDEX idx_name
  ON t (name)

CREATE INDEX で B-tree インデックス作成

SQL Server
CREATE INDEX idx_name
  ON t (name)

CREATE INDEX で B-tree インデックス作成

* INCLUDE (col) で付加列を追加可(カバリングインデックス)

比較メモ: 基本構文は全DBで同一。PostgreSQL は GIN/GiST 等の特殊インデックスが豊富

ユニークインデックス中級
インデックス
MySQL
CREATE UNIQUE INDEX idx_email
  ON t (email)

UNIQUE INDEX で一意制約付きインデックス作成

PostgreSQL
CREATE UNIQUE INDEX idx_email
  ON t (email)

UNIQUE INDEX で一意制約付きインデックス作成

* WHERE句付きの部分ユニークインデックスも可

SQLite
CREATE UNIQUE INDEX idx_email
  ON t (email)

UNIQUE INDEX で一意制約付きインデックス作成

SQL Server
CREATE UNIQUE INDEX idx_email
  ON t (email)

UNIQUE INDEX で一意制約付きインデックス作成

* WHERE句でフィルター付きユニークインデックスも可

比較メモ: UNIQUE INDEX 構文は全DBで同一。PostgreSQL/SQL Server は部分インデックス(WHERE句付き)に対応

ユニーク制約基本
制約
MySQL
CREATE TABLE t (
  email VARCHAR(255) UNIQUE
);
-- または
ALTER TABLE t
  ADD CONSTRAINT uq_email
  UNIQUE (email)

UNIQUE 制約で一意性を保証

PostgreSQL
CREATE TABLE t (
  email TEXT UNIQUE
);
-- または
ALTER TABLE t
  ADD CONSTRAINT uq_email
  UNIQUE (email)

UNIQUE 制約で一意性を保証

* NULLS NOT DISTINCT(15以降)で NULL も重複チェック対象に

SQLite
CREATE TABLE t (
  email TEXT UNIQUE
);
-- ALTER TABLE での追加は不可

CREATE TABLE 時に UNIQUE を指定

* ALTER TABLE で制約追加は非対応。テーブル再作成が必要

SQL Server
CREATE TABLE t (
  email NVARCHAR(255) UNIQUE
);
-- または
ALTER TABLE t
  ADD CONSTRAINT uq_email
  UNIQUE (email)

UNIQUE 制約で一意性を保証

* NULL は1つのみ許容(ANSI_NULLS設定による)

比較メモ: SQLite は ALTER TABLE での制約追加が不可。NULLの扱い: PostgreSQL 15以降は NULLS NOT DISTINCT を選択可能

外部キー制約中級
制約
MySQL
CREATE TABLE orders (
  id INT PRIMARY KEY,
  user_id INT,
  FOREIGN KEY (user_id)
    REFERENCES users(id)
    ON DELETE CASCADE
)

外部キー制約で参照整合性を保証

* InnoDB のみ対応。ON DELETE CASCADE / SET NULL / RESTRICT

PostgreSQL
CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  user_id INTEGER
    REFERENCES users(id)
    ON DELETE CASCADE
)

外部キー制約で参照整合性を保証

* DEFERRABLE INITIALLY DEFERRED でトランザクション終了時チェックも可

SQLite
CREATE TABLE orders (
  id INTEGER PRIMARY KEY,
  user_id INTEGER
    REFERENCES users(id)
    ON DELETE CASCADE
);
-- PRAGMA foreign_keys = ON; が必要

外部キー制約(デフォルト無効)

* PRAGMA foreign_keys = ON を毎接続で実行が必要

SQL Server
CREATE TABLE orders (
  id INT PRIMARY KEY,
  user_id INT
    REFERENCES users(id)
    ON DELETE CASCADE
)

外部キー制約で参照整合性を保証

比較メモ: SQLite は外部キーがデフォルト無効(PRAGMA foreign_keys = ON が必要)。MySQL は InnoDB のみ対応

トランザクション構文中級
トランザクション
MySQL
START TRANSACTION;

UPDATE t SET balance = balance - 100
  WHERE id = 1;
UPDATE t SET balance = balance + 100
  WHERE id = 2;

COMMIT;

START TRANSACTION で開始、COMMIT で確定

* BEGIN も使用可能。autocommit=0 で暗黙トランザクション

PostgreSQL
BEGIN;

UPDATE t SET balance = balance - 100
  WHERE id = 1;
UPDATE t SET balance = balance + 100
  WHERE id = 2;

COMMIT;

BEGIN で開始、COMMIT で確定

* SAVEPOINT sp1 で中間セーブポイントも可

SQLite
BEGIN TRANSACTION;

UPDATE t SET balance = balance - 100
  WHERE id = 1;
UPDATE t SET balance = balance + 100
  WHERE id = 2;

COMMIT;

BEGIN TRANSACTION で開始、COMMIT で確定

* デフォルトで各文がオートコミット

SQL Server
BEGIN TRANSACTION;

UPDATE t SET balance = balance - 100
  WHERE id = 1;
UPDATE t SET balance = balance + 100
  WHERE id = 2;

COMMIT;

BEGIN TRANSACTION で開始、COMMIT で確定

* BEGIN TRAN も可。TRY-CATCH と組み合わせてエラーハンドリング

比較メモ: MySQL は START TRANSACTION、PostgreSQL は BEGIN、SQLite/SQL Server は BEGIN TRANSACTION が標準。COMMIT/ROLLBACK は共通

セーブポイント応用
トランザクション
MySQL
START TRANSACTION;

INSERT INTO t VALUES (1, 'A');
SAVEPOINT sp1;

INSERT INTO t VALUES (2, 'B');
ROLLBACK TO sp1;

COMMIT;
-- 1行目のみ確定

SAVEPOINT + ROLLBACK TO で部分ロールバック

* RELEASE SAVEPOINT sp1 でセーブポイント解放

PostgreSQL
BEGIN;

INSERT INTO t VALUES (1, 'A');
SAVEPOINT sp1;

INSERT INTO t VALUES (2, 'B');
ROLLBACK TO sp1;

COMMIT;
-- 1行目のみ確定

SAVEPOINT + ROLLBACK TO で部分ロールバック

* エラー発生後も ROLLBACK TO で処理を継続可能

SQLite
BEGIN;

INSERT INTO t VALUES (1, 'A');
SAVEPOINT sp1;

INSERT INTO t VALUES (2, 'B');
ROLLBACK TO sp1;

COMMIT;
-- 1行目のみ確定

SAVEPOINT + ROLLBACK TO で部分ロールバック

* ネストしたトランザクションの代替としても使用

SQL Server
BEGIN TRANSACTION;

INSERT INTO t VALUES (1, 'A');
SAVE TRANSACTION sp1;

INSERT INTO t VALUES (2, 'B');
ROLLBACK TRANSACTION sp1;

COMMIT;
-- 1行目のみ確定

SAVE TRANSACTION + ROLLBACK TRANSACTION で部分ロールバック

* SAVEPOINT ではなく SAVE TRANSACTION 構文

比較メモ: SQL Server のみ SAVE TRANSACTION / ROLLBACK TRANSACTION 構文。他3つは SAVEPOINT / ROLLBACK TO 構文

よくある質問

MySQL から PostgreSQL に移行する際に注意すべきSQL構文の違いは何ですか?

主な違いは以下の通りです。(1) AUTO_INCREMENT → SERIAL または GENERATED ALWAYS AS IDENTITY に変更が必要です。(2) IFNULL() → COALESCE() に統一が推奨されます。(3) GROUP_CONCAT() → STRING_AGG() に変更します。(4) バッククォート(`)によるエスケープ → ダブルクォート(")に変更します。(5) LIMIT句は同じですが、OFFSET-FETCH構文も使えます。(6) || 演算子は PostgreSQL では文字列連結ですが、MySQL ではデフォルトで論理OR です。移行時はこれらの構文差を体系的にチェックすることで、多くのエラーを未然に防げます。

SQLite の制限事項(ALTER TABLE の制約など)にはどのようなものがありますか?

SQLite は軽量さと引き換えに以下の制限があります。(1) ALTER TABLE でカラムの型変更・削除ができません(3.35.0以降でDROP COLUMNは対応)。型変更には新テーブル作成→データ移行→リネームが必要です。(2) BOOLEAN や DATE などの専用型がなく、TEXT/INTEGER/REAL/BLOB/NULL の5つの型親和性で管理されます。(3) 外部キー制約はデフォルト無効で、PRAGMA foreign_keys = ON を毎接続で実行する必要があります。(4) ストアドプロシージャ・変数宣言・手続き型IF文が使えません。(5) RIGHT JOIN や FULL OUTER JOIN は 3.39.0 以降で対応。これらの制限を理解した上で設計すれば、組込みDBとして非常に強力です。

SQL Server 固有の構文(TOP, IDENTITY など)にはどのようなものがありますか?

SQL Server には多くの固有構文があります。(1) TOP n: LIMIT の代わりに SELECT TOP 10 * FROM t で行数制限。OFFSET-FETCH も使用可。(2) IDENTITY(1,1): AUTO_INCREMENT の代わりに連番を生成。(3) NVARCHAR: 日本語を扱う場合は VARCHAR ではなく NVARCHAR を使用。(4) #テーブル名: 一時テーブルは # プレフィックスで作成。## でグローバル一時テーブル。(5) @変数名: ローカル変数は @ プレフィックスで宣言。(6) sp_rename: カラム名・テーブル名の変更は ALTER TABLE ではなくストアドプロシージャを使用。(7) GO: バッチ区切り記号(SQL文ではなくクライアントツールの区切り)。(8) MERGE文のセミコロン必須。

UPSERT の各DB間の違いは何ですか?

UPSERT(INSERT or UPDATE)は DB毎に構文が大きく異なります。MySQL は INSERT ... ON DUPLICATE KEY UPDATE で、重複キーの検出は PRIMARY KEY または UNIQUE インデックスに基づきます。PostgreSQL は INSERT ... ON CONFLICT (column) DO UPDATE SET ... で、競合対象のカラムを明示的に指定します(DO NOTHING で無視も可能)。SQLite も PostgreSQL と同じ ON CONFLICT 構文を使います(3.24.0以降)。SQL Server は MERGE 文を使用し、USING句でソースデータを指定、WHEN MATCHED / WHEN NOT MATCHED で更新・挿入の条件を分けます。MERGE 文はセミコロン必須で、最も冗長ですが最も柔軟です。移植性を重視するなら、SELECT で存在確認 → UPDATE or INSERT の2文に分ける方法が最も互換性が高いです。

JSON型のサポート状況はどのように異なりますか?

JSON サポートは DB によって大きく異なります。PostgreSQL が最も充実しており、JSON(テキスト格納)と JSONB(バイナリ格納)の2つの型を持ち、GIN インデックスによる高速検索、@>(包含)や ?(キー存在)などの豊富な演算子が使えます。MySQL は 5.7 以降で JSON 型をネイティブサポートし、->>演算子やJSON_EXTRACT()でアクセスできます。インデックスは仮想カラム経由です。SQLite は専用型はありませんが、TEXT にJSON を格納し、json()、json_extract()、3.38.0以降は -> / ->> 演算子で操作できます。SQL Server は専用型がなく NVARCHAR(MAX) にJSON を格納し、OPENJSON()、JSON_VALUE()、JSON_QUERY()で操作します(2016以降)。本格的なJSONデータベース用途なら PostgreSQL の JSONB が最適です。

ウィンドウ関数の対応状況はどう違いますか?

ウィンドウ関数(ROW_NUMBER, RANK, DENSE_RANK, NTILE, LAG, LEAD 等)の構文は全DBで統一されていますが、対応時期が異なります。最も早くから対応したのは SQL Server(2005年)で、次に PostgreSQL(8.4, 2009年)、SQLite(3.25.0, 2018年)、最も遅いのが MySQL(8.0, 2018年)です。構文は SELECT col, ROW_NUMBER() OVER (PARTITION BY group_col ORDER BY sort_col) FROM t で全DBで同一です。MySQL 5.7 以前を使っている場合はウィンドウ関数が使えないため、サブクエリと変数を使った代替が必要になります。フレーム指定(ROWS BETWEEN ... AND ...)も全DBでサポートされています。

データはいつ更新されますか?

最終更新日: 2026-04-13。MySQL 8.x、PostgreSQL 15/16、SQLite 3.x(最新安定版)、SQL Server 2022 の構文を基準に掲載しています。各DBの新バージョンで構文が追加・変更された場合は随時更新します。なお、古いバージョンでは一部の構文が使用できない場合がありますので、ご利用のDBバージョンのドキュメントもあわせて確認してください。

正規表現のサポート状況の違いは何ですか?

正規表現のサポートはDB毎に大きく異なります。MySQL は REGEXP / RLIKE 演算子で正規表現マッチが可能で、8.0以降はICU正規表現エンジンを採用しています。REGEXP_LIKE()、REGEXP_REPLACE()、REGEXP_SUBSTR() 等の関数もあります。PostgreSQL は ~ 演算子(大文字小文字区別)/ ~*(区別なし)でマッチでき、POSIX正規表現をフルサポートしています。regexp_match()、regexp_replace()、regexp_split_to_table() 等の関数も豊富です。SQLite は標準では REGEXP が未実装で、アプリケーション側でユーザー定義関数として regexp() を登録する必要があります。SQL Server はネイティブの正規表現サポートがなく、LIKE のパターン(% _ [])でごく基本的なマッチのみ可能です。フル正規表現が必要な場合は CLR 統合でカスタム関数を作成するか、アプリケーション側で処理します。

逆引き・早見表ツール一覧

すべて見る

このツールについて

使い方

  1. 検索欄にやりたいこと(例: UPSERT)やSQL構文(例: VARCHAR)を入力する
  2. 「MySQL」「PostgreSQL」「SQLite」「SQL Server」のフィルターで見たいDBに絞り込む
  3. カテゴリドロップダウンでデータ型・DDL・DML等の種類別に絞り込む
  4. 難易度フィルター(基本・中級・応用)で自分のレベルに合ったSQL構文を探す

このツールの特徴

  • 4つのDBを横断比較:MySQL・PostgreSQL・SQLite・SQL Serverの同じ操作に対応するSQL構文を並べて表示します。DB移行時に「あの操作、このDBではどう書く?」をすぐ解決できます
  • 「やりたいこと」から逆引き:「UPSERTしたい」「日付をフォーマットしたい」など、操作の目的からSQL構文を検索できます
  • 実際に使えるコードスニペット:各DB の SQL構文を具体的なコード例で表示。コピーしてすぐに使えます
  • 比較メモで差異を解説:同じ操作でも DB によって挙動が異なるポイント(例: SQLite は ALTER TABLE での型変更不可)を比較メモで補足しています
  • データ型からDDL・DML・関数まで網羅:データ型、テーブル操作、データ操作、文字列・日付・集約・数学関数、制御構文、インデックス、制約、トランザクションまで幅広くカバーしています

こんなときに便利

  • MySQL から PostgreSQL にデータベースを移行するプロジェクトで、構文の違いを把握したい
  • 本番は PostgreSQL だがローカル開発で SQLite を使っていて、対応状況を確認したい
  • 複数のプロジェクトで異なるDBを使っていて、構文を混同しがち
  • 「UPSERT PostgreSQL」「日付フォーマット MySQL」のような構文差をすぐ確認したい
  • 新しいDBを学び始めて、既に知っているDBとの違いを効率的に把握したい

なぜ「SQL方言 横断検索」が必要なのか

SQLは国際標準規格(ISO/IEC 9075)で定義されていますが、実際の実装は各DBエンジンによって大きく異なります。同じ「自動採番」でも MySQL は AUTO_INCREMENT、PostgreSQL は SERIAL / IDENTITY、SQLite は AUTOINCREMENT、SQL Server は IDENTITY(1,1) と、構文がすべて異なります。日付関数やUPSERT構文に至っては、4つのDB間でほぼ互換性がありません。

既存のSQL リファレンスは「MySQL の使い方」「PostgreSQL の使い方」のように単一DBに特化したものがほとんどです。4つのDBを横断的に比較し、「やりたい操作」をキーに逆引きできる日本語ツールはほとんど存在しません。

このツールは「やりたいこと」を起点に、4つのDBのSQL構文を一覧比較することで、DB間の移行コストを最小化し、開発者の日常の作業効率を向上させることを目指しています。特に複数のプロジェクトで異なるDBを扱うエンジニアや、DB移行プロジェクトに携わるチームにとって、構文差の確認時間を大幅に削減できます。

各DBの特徴

  • MySQL:世界で最も広く使われているオープンソースRDBMS。Web アプリケーション(WordPress, Drupal 等)のバックエンドとして圧倒的なシェアを持ちます。InnoDB ストレージエンジンによる ACID トランザクション、レプリケーション、JSON 型サポート(5.7以降)、ウィンドウ関数(8.0以降)を備えています。LAMP スタック(Linux+Apache+MySQL+PHP)の定番です。
  • PostgreSQL:最も高機能なオープンソースRDBMS。SQL標準への準拠度が高く、JSONB 型、配列型、範囲型、全文検索、GIS(PostGIS)、CTE、ウィンドウ関数など先進的な機能を早くから実装しています。DISTINCT ON、RETURNING 句、LISTEN/NOTIFY などの独自拡張も強力です。Ruby on Rails や Django で標準的に使われます。
  • SQLite:サーバーレスの組込みデータベース。ファイル1つで動作し、設定不要で使えるため、モバイルアプリ(iOS/Android)、デスクトップアプリ、IoT 機器、テストやプロトタイピングに最適です。動的型付けシステム(型親和性)を採用しており、他のDBとは設計思想が異なります。機能制限がありますが、軽量さと信頼性で広く採用されています。
  • SQL Server:Microsoft が提供するエンタープライズRDBMS。T-SQL(Transact-SQL)という独自の SQL 拡張を持ち、MERGE 文、IDENTITY、NVARCHAR、@変数、#一時テーブル、sp_rename などの固有構文があります。Windows 環境との親和性が高く、Active Directory 認証、SSMS(管理ツール)、SSIS(ETL)、SSRS(レポート)などの統合ツール群が充実しています。Express Edition は無料で利用可能です。