Yii2: Выбор записей из базы по полю, которое содержит в себе несколько значений

422
21 декабря 2016, 02:19

Есть база Projects.

В ней есть поля: id, name, partners, public.

Поле partners является string и содержит данные в таком виде ["22","46","5","42","34","37","36"], эти данные записываются в базу через мультиселект в админке.

Делаю фильтры на фронтенде и возникла проблема с выборкой данных по одному из значений поля partners, нужно сделать такой запрос:

$model = Project::find()->where(['public'=>1])
                ->andWhere(['partners', '42'])
                ->orderBy('name DESC')->all();

В таком виде запрос естественно не проходит, через LIKE работает: ->andWhere(['LIKE', 'partners', '42'], но если значения будут однозначные, то выборка будет неверной.

Подскажите, как правильно сделать выборку по одному из значений данного поля. Возможно данные поля partners следует предварительно пропускать через json_decode, но как это увязать с запросом к базе?

Answer 1

Не очень красивый, но вполне работоспособный вариант:

$partnerId = 42;
$model = Project::find()->where(['public'=>1])
    ->andWhere("(partners LIKE '[\"" . $partnerId . "\",%'
         OR partners LIKE '%,\"" . $partnerId . "\",%'
         OR partners LIKE '%,\"" . $partnerId . "\"]')")
    ->orderBy('name DESC')->all();
Answer 2

В итоге получилось 2 решения, на мой взгляд не такие гибкие, но оба работают:

Первое решение, парсинг поля через json_decode:

$projectId = 6;
$model = Project::find()
    ->where(['public'=>1])
    ->orderBy('date_end DESC')->all();
$projects = [];
foreach($model as $project) {
    $partners = json_decode($project->partners);
    foreach ($partners as $partner) {
        if ($partner == $partnerId) {
            $projects[] = $project->attributes;
        }
    }
}

Второе решение, добавление кавычек для более строго поиска через LIKE (спасибо @P.Fateev за идею):

$partnerId = 6; // Значение приходит из реквеста, понятное дело, что этой строчки нет в итоге
$partnerId = '"' . $partnerId . '"';
$model = Project::find()
   ->where(['public'=>1])
   ->andWhere(['LIKE', 'partners', $partnerId])
   ->orderBy('date_end DESC')->all();

Первое может быть и правильне, но остановился на втором решение, потому что таких параметров несколько и пока багов нет, если возникнут заменю на первое, которое более строго работает и сравнивает значение.

READ ALSO
Подключение к БД средствами Spring с указанием кодировки сессии

Подключение к БД средствами Spring с указанием кодировки сессии

Дело в том, что развернув приложение на хостинге столкнулся с проблемой кодировки, везде использую UTF-8, отследил весь путь и выявил, что с контролёра...

298
MYSQL репликация и работа триггеров

MYSQL репликация и работа триггеров

Добрый деньИмеется настроенная репликация Master-Slave На Slave необходимо добавить триггеры что бы не нагружать основную базу

278
Выборка из mysql

Выборка из mysql

Есть 2 таблицы: users и objectsВ users хранятся id, name, type и т

260
Mysql не возвращает результат запроса

Mysql не возвращает результат запроса

Совсем ничего не понимаю, запрос, вроде, правильныйНо не выводит строку с нужным id;

264