SQL Functions
\Kotchasan\Database\Sql is a helper class for creating SQL functions that support multiple databases.
Usage
use Kotchasan\Database\Sql;
// In SELECT
$query = Model::createQuery()
->select('id', Sql::COUNT('*', 'total'))
->from('orders')
->groupBy('status');
// In WHERE
$query->where(Sql::BETWEEN('created_at', '2024-01-01', '2024-12-31'));
Note: If you need a column reference inside a function parameter, use Sql::column('column_name'). Plain strings are treated as literal values. You can also use Sql::_strValue('N/A') to make intent explicit.
Aggregate Functions
COUNT()
Sql::COUNT(); // COUNT(*)
Sql::COUNT('*', 'total'); // COUNT(*) as total
Sql::COUNT('id', 'cnt', true); // COUNT(DISTINCT id) as cnt
SUM() / AVG() / MIN() / MAX()
Sql::SUM('total', 'sum_total');
Sql::AVG('price', 'avg_price');
Sql::MIN('created_at', 'first_order');
Sql::MAX('created_at', 'last_order');
String Functions
CONCAT()
// CONCAT(first_name, ' ', last_name) as fullname
Sql::CONCAT(['first_name', "' '", 'last_name'], 'fullname');
// CONCAT_WS(' ', first_name, last_name)
Sql::CONCAT(['first_name', 'last_name'], 'fullname', ' ');
GROUP_CONCAT()
// GROUP_CONCAT(name SEPARATOR ', ')
Sql::GROUP_CONCAT('name', 'names', ', ');
// GROUP_CONCAT(DISTINCT name ORDER BY name)
Sql::GROUP_CONCAT('name', 'names', ',', true, 'name');
LENGTH() / UPPER() / LOWER()
Sql::LENGTH('content', 'char_count');
Sql::UPPER('name', 'name_upper');
Sql::LOWER('email', 'email_lower');
TRIM() / LTRIM() / RTRIM()
Sql::TRIM('name', 'clean_name');
Sql::LTRIM('name');
Sql::RTRIM('name');
SUBSTRING() / REPLACE()
// SUBSTRING(content, 1, 100)
Sql::SUBSTRING('content', 1, 100, 'preview');
// REPLACE(content, 'old', 'new')
Sql::REPLACE('content', 'old', 'new', 'updated');
// Use column reference for search/replace
Sql::REPLACE('content', Sql::column('old'), 'new', 'updated');
Date Functions
NOW() / CURDATE() / CURTIME()
Sql::NOW(); // NOW()
Sql::CURDATE(); // CURDATE()
Sql::CURTIME(); // CURTIME()
DATE() / YEAR() / MONTH() / DAY()
Sql::DATE('created_at', 'date_only'); // DATE(created_at)
Sql::YEAR('created_at', 'year'); // YEAR(created_at)
Sql::MONTH('created_at', 'month'); // MONTH(created_at)
Sql::DAY('created_at', 'day'); // DAY(created_at)
// MySQL format
Sql::DATE_FORMAT('created_at', '%Y-%m-%d', 'formatted');
DATEDIFF()
// Days between 2 dates
Sql::DATEDIFF('end_date', 'start_date', 'days');
Conditional Functions
IF()
// IF(status = 1, 'Active', 'Inactive')
Sql::IF_EXPR('status = 1', "'Active'", "'Inactive'", 'status_text');
CASE
Sql::CASE_WHEN([
['status = 1', "'Active'"],
['status = 0', "'Inactive'"]
], "'Unknown'", 'status_label');
IFNULL() / COALESCE()
// IFNULL(phone, 'N/A')
Sql::IFNULL('phone', "'N/A'", 'phone');
// COALESCE(phone, mobile, 'N/A')
Sql::COALESCE(['phone', 'mobile', "'N/A'"], 'contact');
Math Functions
Sql::ABS('value');
Sql::CEIL('value');
Sql::FLOOR('value');
Sql::ROUND('value', 2);
Sql::RAND();
Comparison
BETWEEN
// price BETWEEN 100 AND 1000
Sql::BETWEEN('price', 100, 1000);
IN / NOT IN
Sql::IN('status', [1, 2, 3]);
Sql::NOT_IN('status', [0, -1]);
Note: If the list is empty, IN() returns a 0=1 expression and NOT_IN() returns 1=1 to avoid invalid SQL.
DISTINCT
Sql::DISTINCT('category');
Method Reference
Aggregate
| Method |
Description |
|---|
COUNT($col, $alias, $distinct) |
Count rows |
SUM($col, $alias) |
Sum of values |
AVG($col, $alias, $distinct) |
Average of values |
MIN($col, $alias) |
Minimum value |
MAX($col, $alias) |
Maximum value |
String
| Method |
Description |
|---|
CONCAT($fields, $alias, $sep) |
Concatenate strings |
GROUP_CONCAT($fields, $alias, $sep, $distinct, $order) |
Concatenate strings in group |
LENGTH($col, $alias) |
String length |
UPPER($col, $alias) |
Convert to uppercase |
LOWER($col, $alias) |
Convert to lowercase |
TRIM($col, $alias) |
Trim whitespace |
LTRIM($col, $alias) |
Trim left whitespace |
RTRIM($col, $alias) |
Trim right whitespace |
SUBSTRING($col, $start, $len, $alias) |
Substring |
REPLACE($col, $search, $replace, $alias) |
Replace string |
Date
| Method |
Description |
|---|
NOW() |
Current date and time |
CURDATE() |
Current date |
CURTIME() |
Current time |
DATE($col, $alias) |
Extract date |
YEAR($col, $alias) |
Extract year |
MONTH($col, $alias) |
Extract month |
DAY($col, $alias) |
Extract day |
DATE_FORMAT($col, $format, $alias) |
Format date |
DATEDIFF($col1, $col2, $alias) |
Date difference |
Conditional
| Method |
Description |
|---|
IF_EXPR($cond, $true, $false, $alias) |
IF condition |
CASE_WHEN($cases, $else, $alias) |
CASE expression |
IFNULL($col, $default, $alias) |
Default if null |
COALESCE($values, $alias) |
First non-null value |
Math
| Method |
Description |
|---|
ABS($col, $alias) |
Absolute value |
CEIL($col, $alias) |
Ceiling |
FLOOR($col, $alias) |
Floor |
ROUND($col, $precision, $alias) |
Round with precision |
Comparison
| Method |
Description |
|---|
BETWEEN($col, $min, $max) |
Between range |
IN($col, $values) |
In list |
NOT_IN($col, $values) |
Not in list |