Medoo

开始

更新日志

Where 语句

查询

聚合

Fetch

事务

管理

原生SQL查询

Raw object

PDO object

Debug

数据库信息

WHERE 语法

Medoo 的一些函数需要 $where 参数来过滤记录,类似于 SQL 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')

您不仅可以使用单个字符串或数字值,还可以使用数组。

$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')
否定条件
$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
// "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')

要纠正这个问题,只需为每个 AND 和 OR 键名分配一个注释(# 加一个空格)。注释内容可以是任何内容。

$database->select("account", '*', [
	"AND #实际上,这个注释功能可以用于每个 AND 和 OR 关系条件" => [
		"OR #第一个条件" => [
			"user_name" => "foo",
			"email" => "foo@bar.com"
		],
		"OR #第二个条件" => [
			"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%'
分组
$database->select("person", "id", [
	"city[~]" => ["lon", "foo", "bar"]
]);
// WHERE "city" LIKE '%lon%' OR "city" LIKE '%foo%' OR "city" LIKE '%bar%'
否定条件
$database->select("person", "id", [
	"city[!~]" => "lon"
]);
// WHERE "city" NOT LIKE '%lon%'
复合条件
$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, Türkmenistan
]);
 
$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...
]);

排序条件

$database->select("account", "user_id", [
	// 单一条件。
	"ORDER" => "user_id",
 
	// 多重条件。
	"ORDER" => [
		// 按列排序,按自定义顺序排序。
		"user_id" => [43, 12, 57, 98, 144, 1],
 
		// 按列排序。
		"register_date",
 
		// 按列降序排序。
		"profile_id" => "DESC",
 
		// 按列升序排序。
		"date" => "ASC"
	]
]);

全文搜索

MySQL 数据库支持全文搜索功能,以获得高级搜索结果。

搜索模式列表
// [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)

使用正则表达式

$data = $database->select('account', [
	'user_id',
	'user_name'
], [
	'user_name[REGEXP]' => '[a-z0-9]*'
]);
// WHERE "user_name" REGEXP '[a-z0-9]*'

使用 SQL 函数

您现在可以使用带有 raw 对象的 SQL 函数进行复杂使用。更多信息请访问 https://medoo.lvtao.net/2.0/doc.raw.php。

$data = $database->select('account', [
	'user_id',
	'user_name'
], [
	'datetime' => Medoo::raw('NOW()')
]);
// WHERE "datetime" = NOW()

LIMIT 和 OFFSET

$database->select("account", "user_id", [
	// 获取前 100 行。
	'LIMIT' => 100,
 
	// 从前 20 行开始,获取接下来的 100 行。
	'LIMIT' => [20, 100],
 
	// 对于 Oracle 和 MSSQL 数据库,您还需要一起使用 ORDER BY。
	'ORDER' => 'location'
]);

GROUP 和 HAVING

$database->select("account", "user_id", [
	'GROUP' => 'type',
 
	// 按值数组分组。
	'GROUP' => [
		'type',
		'age',
		'gender'
	],
 
	'HAVING' => [
		'user_id[>]' => 500
	]
]);