Красноречивый запрос с подсчетом подпунктов - PullRequest
0 голосов
/ 15 мая 2018

У меня есть 2 таблицы:

  • Цепочки значений: id, made_at, updated_at, Удаленный_ат
  • Сегменты: id, valuechain_id (Внешний ключ), made_at, updated_at, Удаленный_at

И сводные таблицы (не очень важно здесь).

У меня есть метод с SQL-запросами ...

  • $ valuechains list дает мне список всех цепочек создания стоимости, которые (мягко) не удалены
  • $ valuechainCount подсчитывает количество опубликованных цепочек создания стоимости
  • $ сегментCount подсчитывает количество сегментов для каждой цепочки создания стоимости

Я пытаюсь использовать функцию карты для добавления столбца, которыйсодержит количество сегментов для каждой цепочки создания стоимости ...

public function vcListAndSegmentCount() {
    $valuechainLists = Valuechain::select('valuechains.id', 'lang_valuechain.vcname', 'lang_valuechain.vcshortname')
        ->join('lang_valuechain', 'valuechains.id', '=', 'lang_valuechain.valuechain_id')
        ->join('langs', 'lang_valuechain.lang_id', '=', 'langs.id')
        ->where('langs.isMainlanguage', '=', '1')
        ->whereNull('valuechains.deleted_at')
        ->get();

    $valuechainCount = Valuechain::whereNull('valuechains.deleted_at')->count();

    for ($i=0; $i < $valuechainCount; $i++) {
        $segmentCount[$i] = Segment::whereNull('segments.deleted_at')
            ->where('valuechain_id', '=', $valuechainLists[$i]->id)->count();
    }

    $valuechainLists = $valuechainLists->map(function ($record) use ($segmentCount) {
        $vclists = array_first($segmentCount, function ($value, $key) use ($record) {
            return $value['id'] === $record['valuechain_id'];
        });
        $record['count'] = $vclists;
        return $record;

    });
    dd($valuechainLists);
}

Методы карты добавляет столбец моей выходной коллекции.К сожалению, новая коллекция не дает мне правильное количество сегментов для каждой цепочки создания стоимости ... она только добавляет одно значение ...

Вот что я получаю:

Collection {#380 ▼
  #items: array:4 [▼
    0 => Valuechain {#450 ▼
      ...
      #attributes: array:4 [▼
        "id" => 1
        "vcname" => "Génétique"
        "vcshortname" => "Génétique"
        "count" => 6
      ]
      #original: array:3 [▶]
      ...
    }
    1 => Valuechain {#451 ▼
      ...
      #attributes: array:4 [▼
        "id" => 2
        "vcname" => "Biotruc"
        "vcshortname" => "Biotruc"
        "count" => 6
      ]
      ...
    }
    2 => Valuechain {#452 ▼
      ...
      #attributes: array:4 [▼
        "id" => 3
        "vcname" => "VC3"
        "vcshortname" => "VC3"
        "count" => 6
      ]
      ...
    }
    3 => Valuechain {#453 ▼
      ...
      #attributes: array:4 [▼
        "id" => 4
        "vcname" => "VC4"
        "vcshortname" => "VC4"
        "count" => 6
      ]
      #original: array:3 [▶]
      ...
    }
  ]
}

Я получаю 6, 6, 6 и 6, тогда как количество должно быть 6, 5, 4, 4 ...

Ответы [ 3 ]

0 голосов
/ 18 мая 2018

Добавить ссылку: &$segmentCount

$valuechainLists = $valuechainLists->map(function ($record) use (&$segmentCount) {....

Также я не уверен, что делает ваша array_first функция.

0 голосов
/ 23 мая 2018

Если вы используете Laravel >= 5.2 и если вы определили отношения на моделях, вы можете использовать метод withCount().

Это будет выглядеть примерно так:

 Valuechain::select('valuechains.id', 'lang_valuechain.vcname', 'lang_valuechain.vcshortname')
    ->withCount(['segments' => function ($query) {
        $query->whereNull('deleted_at);
    }])
    ->join('lang_valuechain', 'valuechains.id', '=', 'lang_valuechain.valuechain_id')
    ->join('langs', 'lang_valuechain.lang_id', '=', 'langs.id')
    ->where('langs.isMainlanguage', '=', '1')
    ->whereNull('valuechains.deleted_at')
    ->get()

или если ваша Segment модель использует черту SoftDeletes, то это немного проще:

Valuechain::select('valuechains.id', 'lang_valuechain.vcname', 'lang_valuechain.vcshortname')
    ->withCount('segments')
    ->join('lang_valuechain', 'valuechains.id', '=', 'lang_valuechain.valuechain_id')
    ->join('langs', 'lang_valuechain.lang_id', '=', 'langs.id')
    ->where('langs.isMainlanguage', '=', '1')
    ->whereNull('valuechains.deleted_at')
    ->get()
0 голосов
/ 16 мая 2018

добавить значение счетчика как свойство вместо элемента массива.

 $valuechainLists = $valuechainLists->map(function ($record) use ($segmentCount) {
     $vclists = array_first($segmentCount, function ($value, $key) use ($record) {
         return $value['id'] === $record['valuechain_id'];
     });
     $record->count = $vclists;
     return $record;
 });

Я изменил

$ record ['count'] = $ vclists;

до

$ record-> count = $ vclists;

...