バージョン: v2.3.0
WHERE 構文
一部の Medoo メソッドでは、SQL の
WHERE 句に相当する $where 引数を使ってレコードを絞り込みます。条件を手書きすると複雑になりやすく、SQL インジェクションの原因にもなりかねませんが、Medoo なら構造化されたわかりやすい書き方で安全に WHERE 句を組み立てられます。基本条件
基本的な条件はシンプルに記述できます。カラム名に演算子を追加することで、特に数値項目に対してより高度な比較も行えます。
$database->select("account", "user_name", [
"email" => "foo@bar.com"
]);
// WHERE email = 'foo@bar.com'
$database->select("account", "user_name", [
"user_id" => 200
]);
// WHERE user_id = 200
$database->select("account", "user_name", [
"user_id[>]" => 200
]);
// WHERE user_id > 200
$database->select("account", "user_name", [
"user_id[>=]" => 200
]);
// WHERE user_id >= 200
$database->select("account", "user_name", [
"user_id[!]" => 200
]);
// WHERE user_id != 200
$database->select("account", "user_name", [
"age[<>]" => [200, 500]
]);
// WHERE age BETWEEN 200 AND 500
$database->select("account", "user_name", [
"age[><]" => [200, 500]
]);
// WHERE age NOT BETWEEN 200 AND 500
[<>] 演算子と [><] 演算子は日時値でも使用できます。$database->select("account", "user_name", [
"birthday[<>]" => [date("Y-m-d", mktime(0, 0, 0, 1, 1, 2015)), date("Y-m-d")]
]);
$database->select("account", "user_name", [
"birthday[><]" => [date("Y-m-d", mktime(0, 0, 0, 1, 1, 2015)), date("Y-m-d")]
]);
WHERE ("birthday" BETWEEN '2015-01-01' AND '2017-01-01')
WHERE ("birthday" NOT BETWEEN '2015-01-01' AND '2017-01-01')
単一の文字列や数値だけでなく、配列も渡すことができます。その場合、Medoo は IN 条件を生成します。
$database->select("account", "user_name", [
"OR" => [
"user_id" => [2, 123, 234, 54],
"email" => ["foo@bar.com", "cat@dog.com", "admin@medoo.in"]
]
]);
WHERE
user_id IN (2,123,234,54) OR
email IN ('foo@bar.com','cat@dog.com','admin@medoo.in')
否定条件
[!] 演算子を使うと、!=、NOT IN、IS NOT NULL などの否定条件を表現できます。$database->select("account", "user_name", [
"AND" => [
"user_name[!]" => "foo",
"user_id[!]" => 1024,
"email[!]" => ["foo@bar.com", "cat@dog.com", "admin@medoo.in"],
"city[!]" => null,
"promoted[!]" => true
]
]);
WHERE
"user_name" != 'foo' AND
"user_id" != 1024 AND
"email" NOT IN ('foo@bar.com','cat@dog.com','admin@medoo.in') AND
"city" IS NOT NULL AND
"promoted" != 1
select() または get() の結果を条件の値として使用することもできます。
$database->select("account", "user_name", [
"user_id" => $database->select("post", "user_id", ["comments[>]" => 40])
]);
WHERE user_id IN (2, 51, 321, 3431)
論理条件
論理条件は、複数の式間の関係を記述します。より複雑なクエリを作成するには、AND と OR を使用します。
基本的な使い方
$database->select("account", "user_name", [
"AND" => [
"user_id[>]" => 200,
"age[<>]" => [18, 25],
"gender" => "female"
]
]);
// Medoo は条件を標準で AND で結合します。次のクエリはこれと同等です。
$database->select("account", "user_name", [
"user_id[>]" => 200,
"age[<>]" => [18, 25],
"gender" => "female"
]);
WHERE user_id > 200 AND age BETWEEN 18 AND 25 AND gender = 'female'
$database->select("account", "user_name", [
"OR" => [
"user_id[>]" => 200,
"age[<>]" => [18, 25],
"gender" => "female"
]
]);
WHERE user_id > 200 OR age BETWEEN 18 AND 25 OR gender = 'female'
入れ子になった条件
$database->has("account", [
"AND" => [
"OR" => [
"user_name" => "foo",
"email" => "foo@bar.com"
],
"password" => "12345"
]
]);
WHERE (user_name = 'foo' OR email = 'foo@bar.com') AND password = '12345'
Medoo は配列を使用して論理条件を記述するため、同じ配列内の重複キーは互いに上書きされます。
// これは期待どおりには動作しません。
$database->select("account", '*', [
"AND" => [
"OR" => [
"user_name" => "foo",
"email" => "foo@bar.com"
],
"OR" => [
"user_name" => "bar",
"email" => "bar@foo.com"
]
]
]);
// [X] SELECT * FROM "account" WHERE ("user_name" = 'bar' OR "email" = 'bar@foo.com')
キーの衝突を避けるには、論理キー名の後にコメントを追加します。コメントは # で始まり、任意のテキストを含めることができます。
$database->select("account", '*', [
"AND #AND や OR の論理条件には任意のコメントを付けられます" => [
"OR #1つ目の条件" => [
"user_name" => "foo",
"email" => "foo@bar.com"
],
"OR #2つ目の条件" => [
"user_name" => "bar",
"email" => "bar@foo.com"
]
]
]);
WHERE (
("user_name" = 'foo' OR "email" = 'foo@bar.com')
AND
("user_name" = 'bar' OR "email" = 'bar@foo.com')
)
カラム同士の比較
$database->select("post", [
"[>]account" => "user_id",
], [
"post.content"
], [
// 完全修飾のカラム名に [=]、[>]、[<]、[!=] などの演算子を付けてカラム同士を比較します。
"post.restrict[<]account.age"
]);
WHERE "post"."restrict" < "account"."age"
LIKE 条件
[~] 演算子を使用して LIKE 条件を作成します。基本条件と論理条件の両方で使用できます。// デフォルトでは、キーワードの前後に % が付き、部分一致で検索されます。
$database->select("person", "id", [
"city[~]" => "lon"
]);
WHERE "city" LIKE '%lon%'
複数キーワードの LIKE 条件
$database->select("person", "id", [
"city[~]" => ["lon", "foo", "bar"]
]);
WHERE "city" LIKE '%lon%' OR "city" LIKE '%foo%' OR "city" LIKE '%bar%'
否定の LIKE 条件
$database->select("person", "id", [
"city[!~]" => "lon"
]);
WHERE "city" NOT LIKE '%lon%'
複合 LIKE 条件
$database->select("person", "id", [
"content[~]" => ["AND" => ["lon", "on"]]
]);
WHERE ("content" LIKE '%lon%' AND "content" LIKE '%on%')
$database->select("person", "id", [
"content[~]" => ["OR" => ["lon", "on"]]
]);
WHERE ("content" LIKE '%lon%' OR "content" LIKE '%on%')
SQL ワイルドカード
SQL のワイルドカードパターンを使うと、より柔軟な照合が行えます。
$database->select("person", "id", [
"city[~]" => "%stan" // Kazakhstan, Uzbekistan, Turkmenistan
]);
$database->select("person", "id", [
"city[~]" => "Londo_" // London, Londox, Londos, ...
]);
$database->select("person", "id", [
"name[~]" => "[BCR]at" // Bat, Cat, Rat
]);
$database->select("person", "id", [
"name[~]" => "[!BCR]at" // Eat, Fat, Hat, ...
]);
並び順の指定
ORDER 句を使って結果セットを並べ替えます。// 単一の列で並び替えます。
$database->select("account", "user_id", [
"ORDER" => "user_id"
]);
// 複数の列で並び替えます。
$database->select("account", "user_id", [
"ORDER" => [
// 列をカスタム順で並び替えます。
"user_id" => [43, 12, 57, 98, 144, 1],
// 列を既定の方向で並び替えます。
"register_date",
// 降順で並び替えます。
"profile_id" => "DESC",
// 昇順で並び替えます。
"date" => "ASC"
]
]);
全文検索
全文検索は、より高度な検索を行うために MySQL がサポートしている機能です。
検索モード
| natural | 自然言語モード |
| natural+query | クエリ拡張付きの自然言語モード |
| boolean | ブールモード |
| query | クエリ拡張 |
// MATCH 条件です。
$database->select("post_table", "post_id", [
"MATCH" => [
"columns" => ["content", "title"],
"keyword" => "foo",
// 任意: 検索モード。
"mode" => "natural"
]
]);
WHERE MATCH (content, title) AGAINST ('foo' IN NATURAL LANGUAGE MODE)
正規表現
[REGEXP] 演算子を使用して、値を正規表現と照合します。
$data = $database->select('account', [
'user_id',
'user_name'
], [
'user_name[REGEXP]' => '[a-z0-9]*'
]);
WHERE "user_name" REGEXP '[a-z0-9]*'
SQL 関数
より複雑なケースでは、Raw オブジェクト経由で SQL 関数を使用できます。詳細は raw ドキュメントを参照してください。
$data = $database->select('account', [
'user_id',
'user_name'
], [
'datetime' => Medoo::raw('NOW()')
]);
WHERE "datetime" = NOW()
LIMIT と OFFSET
LIMIT を使用して、返される行数を制限します。オフセットを指定することもできます。
// 最初の 100 行を返します。
$database->select("account", "user_id", [
"LIMIT" => 100
]);
// 最初の 20 行をスキップし、その次の 100 行を返します。
$database->select("account", "user_id", [
"LIMIT" => [20, 100]
]);
// Oracle と MSSQL では ORDER BY も必要です。
$database->select("account", "user_id", [
"LIMIT" => [20, 100],
"ORDER" => "location"
]);
GROUP BY と HAVING
行をグループ化するには GROUP を使用し、グループ化された結果をフィルターするには HAVING を使用します。
// 単一の列でグループ化します。
$database->select("account", "user_id", [
"GROUP" => "type"
]);
// 複数の列でグループ化します。
$database->select("account", "user_id", [
"GROUP" => [
"type",
"age",
"gender"
]
]);
// 行をグループ化し、その結果を絞り込みます。
$database->select("account", "user_id", [
"GROUP" => "type",
"HAVING" => [
"user_id[>]" => 500
]
]);