PHPackages                             mattsplat/table-queries - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. mattsplat/table-queries

ActiveLibrary[Database &amp; ORM](/categories/database)

mattsplat/table-queries
=======================

Laravel package to easily implement table search, sorts and relational data

0.0.3(6y ago)1491MITPHPPHP ^7.2

Since Oct 7Pushed 6y ago2 watchersCompare

[ Source](https://github.com/mattsplat/laravel-table-queries)[ Packagist](https://packagist.org/packages/mattsplat/table-queries)[ RSS](/packages/mattsplat-table-queries/feed)WikiDiscussions master Synced today

READMEChangelog (2)Dependencies (5)Versions (5)Used By (0)

Laravel Table Queries
=====================

[](#laravel-table-queries)

### Contents

[](#contents)

### [What Is It?](#what)

[](#what-is-it)

### [Setup](#setup)

[](#setup)

#### [Sorting](#sorting)

[](#sorting)

#### [Searching](#searching)

[](#searching)

#### [Relationships](#relationships)

[](#relationships)

#### [Filters](#filters)

[](#filters)

What Is It?
--------------------------------------------

[](#what-is-it-1)

If you need to view your data in table or similar format that combines data from relational models and you need perforance that the client side can't provide. With a large dataset it can become too slow for the client to render so we can use server side rendering. If we rely on data that is from a relational table it can be tricky to filter, search or sort by this data. This package is aimed at making this easier.

Say you have the following database structure

```
users-
    id
    name
    company_id

companies-
    id
    name

sales-
    id
    amount
    user_id
    date

```

You might need to display a table of users with a column for company name, total number of sales and total amount of sales in the last year.

You can define the company name as a simple belongs to relationships with `company|name as company_name'`. This is formatted `relation|column  as alias`. The relation must be defined on the model. This will add company\_name to the select statement allowing it to be filtered or sorted.

For total sales we can use `sales|count(*) as sales_count`

In total sales in the last year we want to get the sum of all the sales by using

```
'sales as year_sales' => function ($q) {
    $q->selectRaw('sum(sales.amount)')->where('date', '>', today()->subYear())
}

```

This works similar to using

```
User::with(['sales' => function ($q) { $q->where('date', '>', today()->subYear()) }])

```

but instead of adding the entire relation as nested object it adds a field that can be added to `orderBy` or `where` or accessed like a property of the model.

Setup
---------------------------------------

[](#setup-1)

To install with composer run `composer require mattsplat/table-queries`

For each query a [class](ExampleTableQuery.php) that implements TableQueryable is created. This class would typically called from a controller.

```
$options = $request->only(['query', 'limit', 'page', 'orderBy', 'ascending', 'filter']);

$results = (new NoteTableQuery($options))->get();

return $results;
```

Sorting
-------------------------------------------

[](#sorting-1)

The TableQueryBuilder class accepts options `orderBy` and `ascending` which can be passed as part of the setOptions method.

```
$results = (new TableQueryBuilder($query))
                ->setOptions(['orderBy' => 'name', 'ascending' => true]);

```

or the order method can be called directly and passed a s arguments

```
$results = (new TableQueryBuilder($query))->order($orderBy, $ascending)

```

In either case if `ascending` is not provided then the default order will be `desc`

Searching
-----------------------------------------------

[](#searching-1)

You can search text across many fields even relations fields using the search option.

```
$results = (new TableQueryBuilder($query))
                ->setOptions(['search' => 'something']);

```

or can be called directly

```
$results = (new TableQueryBuilder($query))->search($searchText)

```

Relationships
-------------------------------------------------------

[](#relationships-1)

Relationships can be loaded using the normal with method but this won't work if you need to sort or filter by this data. With an easy to read syntax you can add basic relational data to the query itself.

```
public function relationalColumns()
    {
        return [
            /// relation name | column name as alias
            /// if alias is not supplied it will be relation_column
            'company|name as company',

            /// if name is multiple words it will be interpreted as raw sql
            /// in this case an alias is required
            'company|concat(users.name, "-", users.id) as company_concat',

            /// optionally a callback can be used to modify the query
            /// the column will not be needed here as a select can be added to the query
            'notes as notes_count' => function ($q) {
                return $q->selectRaw('count(*)');
            },
        ];
    }

```

Filters
-------------------------------------------

[](#filters-1)

A filter can be called for an specific column using sql like syntax. Filter array can be passed in the options array in the format `filter=column:operator:value`

```
$filters = [
            'age:>:21',
            'start_date:gte:11/21/2009',
            'id:in:33,44,200'
           ]
$results = (new TableQueryBuilder($query))
                ->setOptions(['filters' => $filters]);

```

Available Operators Include

```
'gt' , '>', 'gte' , '>=', 'eq' , '=', 'lte' , 'map(function ($name, $f) {
    return $name.$f;
})

```

###  Health Score

23

—

LowBetter than 27% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity11

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity46

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~8 days

Total

3

Last Release

2390d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/f0cf90e7e29acd8663e348763679007428d54b8f7a4062e358b93ee981f1e94d?d=identicon)[mattsplat](/maintainers/mattsplat)

---

Top Contributors

[![mattsplat](https://avatars.githubusercontent.com/u/1675848?v=4)](https://github.com/mattsplat "mattsplat (27 commits)")

---

Tags

laraveleloquentrelations

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/mattsplat-table-queries/health.svg)

```
[![Health](https://phpackages.com/badges/mattsplat-table-queries/health.svg)](https://phpackages.com/packages/mattsplat-table-queries)
```

###  Alternatives

[owen-it/laravel-auditing

Audit changes of your Eloquent models in Laravel

3.4k33.0M95](/packages/owen-it-laravel-auditing)[tucker-eric/eloquentfilter

An Eloquent way to filter Eloquent Models

1.8k4.8M26](/packages/tucker-eric-eloquentfilter)[baril/bonsai

An implementation of the Closure Tables pattern for Eloquent.

3593.5k](/packages/baril-bonsai)[toponepercent/baum

Baum is an implementation of the Nested Set pattern for Eloquent models.

3154.7k](/packages/toponepercent-baum)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
