버전: v2.3.0
WHERE 구문
일부 Medoo 메서드는 SQL의 WHERE 절처럼 레코드를 필터링할 수 있도록
$where 인수를 지원합니다. 조건이 복잡해질수록 직접 SQL을 조합하는 일은 번거롭고 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 #첫 번째 조건" => [
"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%'
NOT 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
]
]);