Исползование UNION + ActiveDataProvider

Предварительное обсуждение найденных ошибок перед отправкой их авторам фреймворка, а также внесение новых предложений.
Ответить
tar_m
Сообщения: 140
Зарегистрирован: 2012.12.26, 07:37

Исползование UNION + ActiveDataProvider

Сообщение tar_m »

Встала задачка банальная

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

        $query3 = new Query();
        $query2 = new Query();
        $query = new Query();
        
        
        $query -> select("*") -> from ("tbl_abonent_history");
        $query2 -> select("*") -> from ("tbl_agreement_history");
        
        $query3 -> union($query);
        $query3 -> union($query2);
        
 
Получаю
SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns
The SQL being executed was: SELECT COUNT(*) UNION (
SELECT * FROM `tbl_abonent_history`
) UNION (
SELECT * FROM `tbl_agreement_history`
)
То есть при запросе на общее количество записей если используется UNION то каунты во вложенные UNION не прописываются
tar_m
Сообщения: 140
Зарегистрирован: 2012.12.26, 07:37

Re: Исползование UNION + ActiveDataProvider

Сообщение tar_m »

Ну они собственно и не должны прописыватся, и это даже не рабочий пример но суть остается той же
Использовать

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

        $query2 = new Query();
        $query = new Query();
        
        
        $query -> select("*") -> from ("tbl_abonent_history");
        $query2 -> select("*") -> from ("tbl_agreement_history");
        
        $query -> union($query2);

        
        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);
Такой код пока нельзя
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Исползование UNION + ActiveDataProvider

Сообщение samdark »

Ну, это у вас и в SQL бы не заработало. Для того, чтобы сделать UNION нужно одинаковое число и имена полей в обоих таблицах. Так что вместо * в select надо перечислить нужные поля и при помощи as привести имена к общему виду.
tar_m
Сообщения: 140
Зарегистрирован: 2012.12.26, 07:37

Re: Исползование UNION + ActiveDataProvider

Сообщение tar_m »

Ок а причем тут тогда ActiveDataProvider? :)

Если бы все так было просто...
ошибка возникает когда происходит вызов

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

 $dataProvider->getModels(); 
после

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

 $dataProvider = new ActiveDataProvider([
            'query' => $query,
]);
 
Если мы просто попытаемся запустить сквель то ниче не произайдет так как таблицы имеют одну структуру

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

        $query2 = new Query();
        $query = new Query();
        
        
        $query -> select("*") -> from ("tbl_abonent_history");
        $query2 -> select("*") -> from ("tbl_agreement_history");
        
        $query -> union($query2);
        $query -> all();
 
Такой код работать будет

короткий трейс реальной ошибки
Database Exception – yii\db\Exception

SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns
The SQL being executed was: SELECT COUNT(*) FROM `tbl_abonent_history` UNION (
SELECT * FROM `tbl_agreement_history`
)
array (
0 => '21000',
1 => 1222,
2 => 'The used SELECT statements have a different number of columns',
)

Caused by: PDOException

SQLSTATE[21000]: Cardinality violation: 1222 The used SELECT statements have a different number of columns

in /develop/app/vendor/yiisoft/yii2/db/Command.php at line 397
1. in /develop/app/vendor/yiisoft/yii2/db/Command.php at line 424
419420421422423424425426427428429 if ($e instanceof Exception) {
throw $e;
} else {
$message = $e->getMessage() . "\nThe SQL being executed was: $rawSql";
$errorInfo = $e instanceof \PDOException ? $e->errorInfo : null;
throw new Exception($message, $errorInfo, (int)$e->getCode(), $e);
}
}
}

/**
2. in /develop/app/vendor/yiisoft/yii2/db/Command.php – yii\db\Command::queryInternal() at line 338
3. in /develop/app/vendor/yiisoft/yii2/db/Query.php – yii\db\Command::queryScalar() at line 285
4. in /develop/app/vendor/yiisoft/yii2/db/Query.php – yii\db\Query::queryScalar() at line 193
5. in /develop/app/vendor/yiisoft/yii2/data/ActiveDataProvider.php – yii\db\Query::count() at line 161
6. in /develop/app/vendor/yiisoft/yii2/data/BaseDataProvider.php – yii\data\ActiveDataProvider::prepareTotalCount() at line 145
7. in /develop/app/vendor/yiisoft/yii2/data/ActiveDataProvider.php – yii\data\BaseDataProvider::getTotalCount() at line 104
8. in /develop/app/vendor/yiisoft/yii2/data/BaseDataProvider.php – yii\data\ActiveDataProvider::prepareModels() at line 79
9. in /develop/app/vendor/yiisoft/yii2/data/BaseDataProvider.php – yii\data\BaseDataProvider::prepare() at line 92
10. in /develop/app/modules/agreement/views/history/journal.php – yii\data\BaseDataProvider::getModels() at line 19
1415161718192021222324
GridViewAsset::register($this);

echo JournalHeader::widget(['header' => $this->Message -> journal]);

$models = $dataProvider->getModels();
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Исползование UNION + ActiveDataProvider

Сообщение samdark »

Ага, тут уже занятней. Наобъединялся count и select *.
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Исползование UNION + ActiveDataProvider

Сообщение samdark »

Надо набор для воспроизведения...
tar_m
Сообщения: 140
Зарегистрирован: 2012.12.26, 07:37

Re: Исползование UNION + ActiveDataProvider

Сообщение tar_m »

Надо набор для воспроизведения...
?

Я так понимаю что по этой ошибке ничего не сделано? Может есть предложения как это у себя исправить? хотя бы временно
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Исползование UNION + ActiveDataProvider

Сообщение samdark »

Эту ошибку не удаётся воспроизвести просто так. Нужен zip с минимальным кодом, который покажет ошибку.
tar_m
Сообщения: 140
Зарегистрирован: 2012.12.26, 07:37

Re: Исползование UNION + ActiveDataProvider

Сообщение tar_m »

Все что нужно так это вместо выполнения

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

SELECT count(*) AS cnt FROM table1
UNION
SELECT * AS cnt FROM table2
При присутствии юнион сквель оборачивался таким образом при получиении количества записей

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

SELECT sum(cnt) FROM (
SELECT count(*) AS cnt FROM table1
UNION
SELECT count(*) AS cnt FROM table2
) countAll;

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


        $query2 = new Query();
        $query = new Query();
        
        
        $query -> select("*") -> from ("table1");
        $query2 -> select("*") -> from ("table2");
        
        $query -> union($query2);

        
        $dataProvider = new ActiveDataProvider([
            'query' => $query,
        ]);

        $dataProvider->getModels();
Вот код который вызвает эту ошикбу

таблицы должны содержать больше 1 столбца и иметь одинаковую структуру

Что еще надо, я не понимаю, тут и так все есть
LAV45
Сообщения: 47
Зарегистрирован: 2014.01.16, 22:37

Re: Исползование UNION + ActiveDataProvider

Сообщение LAV45 »

Есть еще ArrayDataProvider
Он не выполняет никаких sql, а просто работает с массивом. Как временный вариант может и подойдет.
tar_m
Сообщения: 140
Зарегистрирован: 2012.12.26, 07:37

Re: Исползование UNION + ActiveDataProvider

Сообщение tar_m »

Какой в этом смысл спустя год?
Да и не в этом тут дело, тут дело в том что не работала (сейчас незнаю) стандартная процедура (как было по гайду) makeа union запроса при попытке получения общего количества строк.
Krash
Сообщения: 29
Зарегистрирован: 2016.04.19, 12:43

Re: Исползование UNION + ActiveDataProvider

Сообщение Krash »

Не работало, потому что вы неправильно использовали конструкцию UNION. Вот и все
Ответить