/ ORM Queries

ORM Query Examples

Advanced examples of using Miko's Query Builder for complex database queries.


Basic Queries

// Select all
$users = User::query()->get();

// Select specific columns
$users = User::select('Id', 'Name', 'Email')->get();

// Where clause
$activeUsers = User::where('IsActive', true)->get();

// Multiple conditions
$admins = User::where('Role', 'admin')
    ->where('IsActive', true)
    ->orderBy('Name')
    ->get();

Complex Where Clauses

Grouped Conditions

$staff = User::where('IsActive', true)
    ->where(function ($q) {
        $q->where('Role', 'admin')
          ->orWhere('Role', 'moderator');
    })
    ->get();

Multiple OR Groups

// (Status = 'active' AND Type = 'premium') OR (Status = 'trial' AND CreatedDate > '2024-01-01')
$users = User::where(function ($q) {
        $q->where('Status', 'active')
          ->where('Type', 'premium');
    })
    ->orWhere(function ($q) {
        $q->where('Status', 'trial')
          ->where('CreatedDate', '>', '2024-01-01');
    })
    ->get();

Dynamic Conditions

$query = User::query();

if ($request['status'] ?? null) {
    $query->where('Status', $request['status']);
}

if ($request['role'] ?? null) {
    $query->where('Role', $request['role']);
}

if ($request['search'] ?? null) {
    $query->whereLike('Name', $request['search'])
          ->orWhereLike('Email', $request['search']);
}

$users = $query->orderBy('Name')->get();

Joins

Inner Join

$orders = Order::query()
    ->join('users', 'orders.UserId', '=', 'users.Id')
    ->select('orders.*', 'users.Name as UserName', 'users.Email')
    ->where('orders.Status', 'completed')
    ->get();

Left Join

$users = User::query()
    ->leftJoin('profiles', 'users.Id', '=', 'profiles.UserId')
    ->select('users.*', 'profiles.Bio', 'profiles.Avatar')
    ->get();

Multiple Joins

$orderDetails = Order::query()
    ->join('users', 'orders.UserId', '=', 'users.Id')
    ->join('order_items', 'orders.Id', '=', 'order_items.OrderId')
    ->join('products', 'order_items.ProductId', '=', 'products.Id')
    ->select(
        'orders.OrderNumber',
        'users.Name as CustomerName',
        'products.Name as ProductName',
        'order_items.Quantity',
        'order_items.UnitPrice'
    )
    ->where('orders.Id', $orderId)
    ->get();

Aggregates & Grouping

Basic Aggregates

$stats = [
    'total_users' => User::count(),
    'active_users' => User::where('IsActive', true)->count(),
    'avg_age' => User::avg('Age'),
    'total_revenue' => Order::where('Status', 'completed')->sum('TotalAmount')
];

Group By

// Users per role
$roleStats = User::query()
    ->select('Role')
    ->selectRaw('COUNT(*) as Count')
    ->groupBy('Role')
    ->get();

// Output: [['Role' => 'admin', 'Count' => 5], ['Role' => 'user', 'Count' => 100], ...]

Group By with Having

// Roles with more than 10 users
$popularRoles = User::query()
    ->select('Role')
    ->selectRaw('COUNT(*) as Count')
    ->groupBy('Role')
    ->having('Count', '>', 10)
    ->orderBy('Count', 'desc')
    ->get();

Complex Aggregates

// Monthly sales report
$monthlySales = Order::query()
    ->selectRaw('YEAR(CreatedDate) as Year')
    ->selectRaw('MONTH(CreatedDate) as Month')
    ->selectRaw('COUNT(*) as OrderCount')
    ->selectRaw('SUM(TotalAmount) as TotalSales')
    ->selectRaw('AVG(TotalAmount) as AvgOrderValue')
    ->where('Status', 'completed')
    ->groupBy('Year', 'Month')
    ->orderBy('Year', 'desc')
    ->orderBy('Month', 'desc')
    ->get();

Subqueries

Where In Subquery

// Users who have placed orders over $1000
$bigSpenders = User::whereIn('Id', function($query) {
    $query->select('UserId')
          ->from('orders')
          ->where('TotalAmount', '>', 1000)
          ->groupBy('UserId');
})->get();

Where Exists

// Users with at least one order
$customersWithOrders = User::whereExists(function($query) {
    $query->select('Id')
          ->from('orders')
          ->whereColumn('orders.UserId', 'users.Id');
})->get();

Raw Expressions

Select Raw

// Calculate age from birth date
$users = User::query()
    ->select('Name', 'Email')
    ->selectRaw('TIMESTAMPDIFF(YEAR, BirthDate, CURDATE()) as Age')
    ->get();

Where Raw

// Full-text search (MySQL)
$results = Article::whereRaw(
    "MATCH(Title, Content) AGAINST(? IN BOOLEAN MODE)",
    ['+php +mysql']
)->get();

// Date functions
$todayOrders = Order::whereRaw('DATE(CreatedDate) = CURDATE()')->get();

Order Raw

// Custom sort order
$users = User::orderByRaw("FIELD(Role, 'admin', 'moderator', 'user')")->get();

// Random order
$randomUsers = User::orderByRaw('RAND()')->take(5)->get();

Pagination Examples

Basic Pagination

$page = (int)($_GET['page'] ?? 1);
$perPage = 20;

$result = User::where('IsActive', true)
    ->orderBy('Name')
    ->paginate($perPage, $page);

// Build pagination links
$links = [];
for ($i = 1; $i <= $result['last_page']; $i++) {
    $links[] = [
        'page' => $i,
        'url' => "/users?page=$i",
        'active' => $i === $result['current_page']
    ];
}

Cursor Pagination (for large datasets)

$lastId = (int)($_GET['after'] ?? 0);
$limit = 20;

$users = User::where('Id', '>', $lastId)
    ->orderBy('Id')
    ->take($limit)
    ->get();

$nextCursor = !empty($users) ? end($users)->Id : null;

Search Implementation

function searchUsers(string $query, array $filters = []): array
{
    $builder = User::query();
    
    // Text search
    if ($query) {
        $builder->whereLike('Name', $query)
              ->orWhereLike('Email', $query)
              ->orWhereLike('Phone', $query);
    }
    
    // Filters
    if ($filters['role'] ?? null) {
        $builder->where('Role', $filters['role']);
    }
    
    if ($filters['status'] ?? null) {
        $builder->where('IsActive', $filters['status'] === 'active');
    }
    
    if ($filters['created_from'] ?? null) {
        $builder->where('CreatedDate', '>=', $filters['created_from']);
    }
    
    if ($filters['created_to'] ?? null) {
        $builder->where('CreatedDate', '<=', $filters['created_to']);
    }
    
    // Sorting
    $sortField = $filters['sort'] ?? 'CreatedDate';
    $sortDir = $filters['order'] ?? 'desc';
    $builder->orderBy($sortField, $sortDir);
    
    // Pagination
    $page = (int)($filters['page'] ?? 1);
    $perPage = (int)($filters['per_page'] ?? 20);
    
    return $builder->paginate($perPage, $page);
}

Report Queries

Sales Dashboard

function getSalesDashboard(): array
{
    $today = date('Y-m-d');
    $thisMonth = date('Y-m-01');
    $thisYear = date('Y-01-01');
    
    return [
        'today' => [
            'orders' => Order::whereDate('CreatedDate', $today)->count(),
            'revenue' => Order::whereDate('CreatedDate', $today)
                ->where('Status', 'completed')
                ->sum('TotalAmount')
        ],
        'this_month' => [
            'orders' => Order::where('CreatedDate', '>=', $thisMonth)->count(),
            'revenue' => Order::where('CreatedDate', '>=', $thisMonth)
                ->where('Status', 'completed')
                ->sum('TotalAmount')
        ],
        'this_year' => [
            'orders' => Order::where('CreatedDate', '>=', $thisYear)->count(),
            'revenue' => Order::where('CreatedDate', '>=', $thisYear)
                ->where('Status', 'completed')
                ->sum('TotalAmount')
        ],
        'top_products' => OrderItem::query()
            ->join('products', 'order_items.ProductId', '=', 'products.Id')
            ->select('products.Name')
            ->selectRaw('SUM(order_items.Quantity) as TotalSold')
            ->selectRaw('SUM(order_items.Quantity * order_items.UnitPrice) as Revenue')
            ->groupBy('products.Id', 'products.Name')
            ->orderBy('TotalSold', 'desc')
            ->take(10)
            ->get()
    ];
}