Как избежать Integrity constraint violation при выполнении связанного запрос в yii

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Clasen01
Сообщения: 15
Зарегистрирован: 2018.04.17, 03:44

Как избежать Integrity constraint violation при выполнении связанного запрос в yii

Сообщение Clasen01 » 2018.04.17, 03:54

Необходимо выполнить запрос из двух таблиц, например, News и ThisDay. Общих данных в них нет, мне просто необходимо получить данные из обоих этих таблиц так, будто это одна выборка. Пытался выполнить путем смерживания двух выборок, но в таком случае выборки из разных таблиц не смешиваются, подробнее здесь https://vk.cc/7XF6pu. При чем из ThisDay будут выбираться все новости за указный день и месяц, а из News будут выбирать так, как указано в условии limit(). Вот сам код выборки:

Код: Выделить всё

$newsFromTwoTables = ThisDay::find()
        ->where(
                new Expression(
                "day = :dateDay"
                . " AND id_region = :id_region"
                . " AND month = :month", [":dateDay" => $dateDay,
            ":month" => $currentMoth,
            ":id_region" => REGION_ID]))
        ->orderBy("news_date DESC")
        ->joinWith('news')
        ->where(
                new Expression("EXTRACT(DAY FROM cdate) = :userDay "
                . "AND id_region = :id_region "
                . "AND EXTRACT(MONTH FROM cdate) = :userMonth "
                . "AND EXTRACT(YEAR FROM cdate) "
                . "AND status > :stat AND n.id NOT IN"
                . " (SELECT id_news FROM this_day)", [":userDay" => $dateDay,
            ":userMonth" => $currentMoth,
            ":id_region" => REGION_ID,
            ":stat" => 1]))
        //новости с самым высоким рейтингом
        ->with("rating nr")
        ->orderBy("nr.rate DESC")
        ->limit(4 - ThisDay::find()
                ->where(
                        new Expression(
                        "day = :dateDay"
                        . " AND id_region = :id_region", [":dateDay" => $dateDay,
                    ":id_region" => REGION_ID]))
                ->count())
        ->orderBy("cdate_int DESC")
        ->groupBy("EXTRACT(YEAR FROM cdate)")
        ->all();
После этого я передаю переменную $newsFromTwoTables в представление, как модель. При попытке открыть представление получаю ошибку, представленную на рисунке ниже.
Изображение

Как можно исправить запрос на выборку так, чтобы избежать этой ошибки?

andku83
Сообщения: 918
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Как избежать Integrity constraint violation при выполнении связанного запрос в yii

Сообщение andku83 » 2018.04.17, 13:54

Код: Выделить всё

...
->select('*')
->asArray()
...
скорее всего еще придется учесть одинаковые имена колонок в разных таблицах, и тогда в select() перечислить все необходимые

Clasen01
Сообщения: 15
Зарегистрирован: 2018.04.17, 03:44

Re: Как избежать Integrity constraint violation при выполнении связанного запрос в yii

Сообщение Clasen01 » 2018.04.17, 18:10

andku83 писал(а):
2018.04.17, 13:54

Код: Выделить всё

...
->select('*')
->asArray()
...
скорее всего еще придется учесть одинаковые имена колонок в разных таблицах, и тогда в select() перечислить все необходимые
А это лишит меня возможности использования функций описанных в классе модели? На данный момент я могу использовать что то вот такое: $model->getAuthorName(); а если я буду массивом работать, используя его как модель данных, то все поломается?

andku83
Сообщения: 918
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Как избежать Integrity constraint violation при выполнении связанного запрос в yii

Сообщение andku83 » 2018.04.17, 20:38

Clasen01 писал(а):
2018.04.17, 18:10
...а если я буду массивом работать, используя его как модель данных, то все поломается?
ДА

Если вы хотите использовать доп поля, тогда для всех этих полей добавьте одноименные публичные свойства.
И в select() запроса:

Код: Выделить всё

...
->select([ThisDay::tableName().'.*', 'date' => new \yii\db\Expression('your_expression'), ...])
...
// или
...
->select([ThisDay::tableName().'.*'])
->addSelect(['date' => new \yii\db\Expression('your_expression'), ...])
...

dmg
Сообщения: 649
Зарегистрирован: 2012.10.15, 03:09

Re: Как избежать Integrity constraint violation при выполнении связанного запрос в yii

Сообщение dmg » 2018.04.17, 22:25

Clasen01 писал(а):
2018.04.17, 03:54
Как можно исправить запрос на выборку так, чтобы избежать этой ошибки?
Добавьте префиксы таблиц к cdate.

andku83
Сообщения: 918
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Как избежать Integrity constraint violation при выполнении связанного запрос в yii

Сообщение andku83 » 2018.04.18, 00:53

и кстати:
1) ->where(1)->where(2) - второе условие удаляет первое, для совмещения обоих нужно использовать ->andWhere()
2) ->orderBy(1)->orderBy(2) - второе условие отменяет первое, для сортировки по обоим параметрам писать в одном общем ->orderBy([1,2]) или использовать ->addOrderBy(2)

Ответить