SQLserverとMySQLの主なクエリの違い

使ってみて気づいた違いを書いていきます。

随時追加予定。

ISNULL -> COALESCE

NULLのときの値置換

WITH (NOLOCK) 使えない

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

のようなSQLを実行しないといけない。

VARCHARではなくCHARで指定

文字列を固定長でキャスト

WHERE USERNAME = CAST(?, CHAR(255))

GETDATE()ではなくNOW()

ほかにCURRENT_TIMESTAMP()がある。ほぼ同じ。

テーブル作成時、サーバー接続時の照合順序

テーブル作成したときの照合順序が ‘ utf8mb4_general_ci’ (テーブルの構造で確認可能)で

サーバー接続時の照合順序が ‘ utf8mb4_unicode_ci ‘ (phpMyAdminのホームで変更可能)のとき、CASTしたとしても、照合順序が違うのでエラーとなってしまう。

テーブルのカラムの照合順序を変えるなら

ALTER TABLE your_table CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;

比較時のCAST時に照合順序を変えるなら

SELECT * FROM your_table_name WHERE CAST(your_column_name AS CHAR CHARACTER SET utf8mb4) = 'your_value';

もしくは
WHERE your_column_name = CAST(? AS CHAR(255)) COLLATE utf8mb4_general_ci;
としていする。

CASTしたときに照合順序が違うのはSQLセッションの照合順序か
PHPのセッションでの照合順序がサーバーやデータベース、カラムの照合順序と違う場合である。
PHP側で変更するときは、php.iniに

session.collation_connection = utf8mb4_general_ci

もしくはini_set()で
ini_set('session.collation_connection', 'utf8mb4_general_ci');

CASTするとgeneral_ciになるなら、テーブルやカラム作成時にgeneral_ciにしておけばいい。

TOP 1ではなく、LIMIT 1 を最後につける

これはそのままの意味で、SELECT LIMIT 1 * FROM ~ としてもだめ。ORDER句よりも後。

一時テーブル##tempTableは無いので作成する

SQL Serverでは、#や##をつければ、一時テーブルとして使えたが、

MySQLでは使えないので、

CREATE TEMPORARY TABLE table_name (
id INT AUTO_INCREMENT PRIMARY KEY,
  name VARCHAR(255)
);

として、テーブルを作成する必要がある。

SELECT * INTO new_table FROM original_tableは使えない

CREATE TABLE new_table AS
SELECT column1, column2, ...
FROM original_table
WHERE condition;

CONVERTの引数の違い

SQLserverでは、

CONVERT(data_type, expression[, style])
変換先のデータ型が、変換する式 の順番。オプションでstyle

MySQLでは、

CONVERT(expression, data_type)
変換する式、変換先のデータ型 の順番

MySQLにはstyleオプションはない。

日付を文字列形式(YYYY/MM/DD)にするとき

SQLserver

CONVERT(VARCHAR, BIRTHDAY, 111) AS BIRTHDAY

MySQL

CONVERT(DATE_FORMAT(BIRTHDAY, '%Y/%m/%d'), CHAR) AS BIRTHDAY


convertではYYYY-MM-DDになるので
 CONVERT(BIRTHDAY, CHAR(10))  AS BIRTHDAY


date_formatを使う

 DATE_FORMAT(BIRTHDAY, 'YYYY/MM/DD') AS BIRTHDAY

FORMAT -> DATE_FORMAT

日付の場合

FORMAT(IYYMDHMS,'yyyy/MM/dd') AS STARTDATE
↓
DATE_FORMAT(l.IYYMDHMS, '%Y/%m/%d') AS SMPLDATE