Laravel объединение из двух таблиц, включая ноль - PullRequest
0 голосов
/ 31 января 2020

У меня есть 3 таблицы listings, cities, state.

listings таблица:

id | city_id | state_id |...|

Модель листинга:

class Listing extends Model{

function city(){
    return $this->belongsTo('App\Models\City');
}

function state(){
    return $this->belongsTo('App\Models\State');
}

Листинг Миграция:

public function up(){
    Schema::create('listings', function (Blueprint $table) {
        $table->integer('id')->unsigned()->index()->unique()->autoIncrement();
        $table->integer('city_id')->nullable();
        $table->integer('state_id')->nullable();
        ....

city_id/state_id может иметь значение NULL!

cities таблица:

id | state_id | name | ...|

City Модель:

class City extends Model{

    public function listings(){
        return $this->hasMany('App\Models\Listing');
    }

    function state(){
        return $this->belongsTo('App\Models\State');
    }

Миграция:

public function up(){
    Schema::create('cities', function (Blueprint $table) {
        $table->integer('id')->unsigned()->index()->unique()->autoIncrement();
        $table->integer('state_id')->nullable();
        $table->string('name');

states Таблица:

id | name ...|

Модель:

class State extends Model{

    public function listings(){
        return $this->hasMany('App\Models\Listing');
    }

    function cities(){
        return $this->hasMany('App\Models\City');
    }

Миграция :

public function up(){
    Schema::create('states', function (Blueprint $table) {
        $table->integer('id')->unsigned()->index()->unique()->autoIncrement();
        $table->string('name');

listings таблица имеет внешние ключи для state_id и city_id. Отношение для обоих - один город или штат ко многим спискам. Таблица

city также имеет внешний ключ state_id и связь одного штата со многими городами.

Я хочу выбрать все из states и cities и посчитать строки из таблицы списков для каждого города / штата, где я могу:

foreach($listings as $listing){
    {{$listing->city or state . ' | ' . $listing->all (count listings for current city/state)}}
}

Я попробовал следующее:

        $locations = DB::table('listings')
        ->join('states', 'states.id', '=', 'listings.state_id')
        ->join('cities', 'cities.id', '=', 'listings.city_id')
        ->groupBy(['listings.city_id', 'listings.state_id' ])

        ->select(
                       'states.name.name as state',
                       'cities.name as city',
                       'states.id as state_id',
                       'city.id as city_id',
                       DB::raw("COUNT(listings.id) as countListings")
                   )->get();

Проблема в том, что я хочу, чтобы все города и штаты в одной коллекции содержали другой ключ / свойство - подсчитайте списки для этого города / штата.

Это город или штат, это не Неважно, я просто хочу их имена с подсчетом списков.

Я использую последнюю версию Laravel с MySQL.

1 Ответ

1 голос
/ 31 января 2020

Не уверен, что он полностью соответствует вашим потребностям, но если вы хотите избежать каких-либо сложных SQL запросов и союзов, вы можете сделать следующее:

$states = State::with(['listings', 'listings_count'])->get();
$cities = City::with(['listings', 'listings_count'])->get();

$locations = $states->merge($cities);

Это не так хорошо с точки зрения производительность, если ваши коллекции будут большими, но все же полезными для небольших коллекций.

...