最終更新日:2025年11月20日

SQL SELECT徹底比較:MySQL・PostgreSQL・SQL Serverでどう書く?

記事内に商品プロモーションを含む場合があります。

SQLの基本であるSELECT文は、どのRDBMSでもほぼ共通して使える一方、細かい仕様やオプションはデータベースによって異なる。
ここでは MySQL・PostgreSQL・SQL Server の3つを横並びで確認しながら、共通点と違いを整理していく。

基本のSELECT構文はほぼ共通

まずは基礎となるSELECT文。どのDBでも以下の構文がそのまま動く。

SELECT column1, column2
FROM table_name
WHERE condition
ORDER BY column1;

このレベルの基本構文は3製品間でほぼ差がないため、学びやすい部分。

LIMIT/OFFSETの違い

ページング処理で最も差が出るポイント。

MySQL

SELECT * FROM users
LIMIT 10 OFFSET 20;

PostgreSQL

SELECT * FROM users
LIMIT 10 OFFSET 20;

MySQLと同じ。

SQL Server

SELECT * FROM users
ORDER BY id
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

SQL ServerだけORDER BYが必須という点が実務でよくつまずく部分。

TOP句

SQL ServerではLIMITが使えず、代わりにTOPが利用可能。

SQL Server

SELECT TOP 10 * FROM users;

MySQLやPostgreSQLではこの構文は使えない。

文字列連結の違い

意外と厄介なのが文字列連結。

MySQL

SELECT CONCAT(first_name, ' ', last_name) FROM users;

PostgreSQL

SELECT first_name || ' ' || last_name FROM users;

SQL Server

SELECT first_name + ' ' + last_name FROM users;

PostgreSQLだけ演算子(||)を使う点に注意。

日付関数の違い

日付を扱う場合は差が大きい。

現在時刻の取得

日付の加算(例:1日後)

SELECT DATE_ADD(NOW(), INTERVAL 1 DAY);
SELECT NOW() + INTERVAL '1 day';
SELECT DATEADD(day, 1, GETDATE());

IF構文・CASE式の違い

MySQL

SELECT IF(score > 80, 'OK', 'NG') FROM results;

PostgreSQL・SQL Server(IFは使えないためCASE)

SELECT CASE WHEN score > 80 THEN 'OK' ELSE 'NG' END
FROM results;

CASE式なら3製品共通で書けるため、互換性を優先するならCASEを使うのが無難。

正規表現の違い

MySQL

SELECT * FROM users WHERE name REGEXP '^A';

PostgreSQL

SELECT * FROM users WHERE name ~ '^A';

SQL Server

標準SQLの正規表現は非対応なため、LIKEやCLR、外部機能を使う。

自動採番(シーケンス/AUTO_INCREMENT/IDENTITY)

MySQL(AUTO_INCREMENT)

id INT AUTO_INCREMENT

PostgreSQL(SERIAL または IDENTITY)

id SERIAL
-- もしくは IDENTITY

SQL Server(IDENTITY)

id INT IDENTITY(1,1)

INSERTしたレコードのID取得方法も微妙に異なるが、SELECT文で参照する分には違いはない。

実務で意識すべきポイントまとめ

共通している部分

差が大きい部分

同じSQLでも、ちょっとした違いが動作や結果に影響するため、マルチDB環境では特にこの辺を押さえておくとトラブルを避けやすい。

まとめ

MySQL・PostgreSQL・SQL Serverは、SELECT文の基本構文こそ共通しているものの、関数やオプションはかなり違いがある。特にページング、日付、文字列などは書き換えが必要になりやすい。

複数のデータベースを扱う場面では、
できるだけ標準SQLで書く/DB専用の関数を使う箇所を把握する
この二つを意識しておくと安定しやすい。

基本比較表

項目MySQLPostgreSQLSQL Server
基本SELECT構文共通共通共通
DISTINCT対応対応対応
ORDER BY共通共通共通
LIMITLIMITLIMIT非対応
OFFSETOFFSETOFFSETOFFSETORDER BY必須)
ページング構文LIMIT 10 OFFSET 20LIMIT 10 OFFSET 20OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY
サブクエリ共通共通共通
JOIN構文共通共通共通

文字列連結の比較

DB連結方法
MySQLCONCAT()CONCAT(a, b)
PostgreSQL`` 演算子`ab`
SQL Server+a + b

正規表現の比較

DB正規表現サポート構文例
MySQL対応name REGEXP '^A'
PostgreSQL対応name ~ '^A'
SQL Server非対応(標準機能)LIKEで代替

日付関数比較

操作MySQLPostgreSQLSQL Server
現在時刻NOW()NOW()GETDATE()
日付加算DATE_ADD(NOW(), INTERVAL 1 DAY)NOW() + INTERVAL '1 day'DATEADD(day, 1, GETDATE())
日付差DATEDIFF()AGE() または演算DATEDIFF()

CASE式比較

DBCASE式サポートIF式
MySQL対応IF(expr, a, b)
PostgreSQL対応非対応
SQL Server対応非対応

互換性重視ならCASE式を使うのが安全。

ページング構文比較(重要)

DB書き方備考
MySQLLIMIT 10 OFFSET 20シンプル
PostgreSQLLIMIT 10 OFFSET 20同じ構文
SQL ServerORDER BY col OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLYORDER BY必須

自動採番列の取得(SELECTで確認する場合)

DBシステムカラム例備考
MySQL専用システム列なし取得はINSERT側の話が中心
PostgreSQLctid内部情報だが取得可能
SQL ServerROW_NUMBER()などウィンドウ関数挙動は標準SQL寄り

ウィンドウ関数(OVER句)

3製品とも対応しており、記述はほぼ共通。

DB対応
MySQL対応(8.0以降)ROW_NUMBER() OVER (ORDER BY id)
PostgreSQL対応同左
SQL Server対応同左

まとめ

特徴MySQLPostgreSQLSQL Server
標準SQLとの親和性
文字列連結のクセ
ページングの違い
正規表現標準機能標準機能非対応
日付関数の差

必要なら、この内容を応用した記事化、コードサンプルの比較、さらに細かい仕様の追加も可能。

SQL SELECT徹底比較:MySQL・PostgreSQL・SQL Serverでどう書く?の商品をアマゾンで調べる。
SQL DELETE徹底比較:MySQL・PostgreSQL・SQL Serverでどう書く?
sect: Sqls | lastmod: 2025-11-20 | pv: 0
SQL INSERT徹底比較:MySQL・PostgreSQL・SQL Serverでどう書く?
sect: Sqls | lastmod: 2025-11-20 | pv: 0
SQL UPDATE徹底比較:MySQL・PostgreSQL・SQL Serverでどう書く?
sect: Sqls | lastmod: 2025-11-20 | pv: 0
SQLServer nolockを使ってテーブルをロックせずにSELECTする
sect: Teches | lastmod: 2019-04-30 | pv: 10121
phpMyAdminでcount(): Parameter must be an array or an object that implements Countable
sect: Teches | lastmod: 2018-11-17 | pv: 20