MySQL Union Все в Yii по умолчанию
Я использую Yii 1.1.16 и задаюсь вопросом, как бы модель Union 2 использовать область по умолчанию?
model 1 = abc
model 2 = abc2
В основном я хочу сделать простой союз
SELECT * FROM `abc`
UNION ALL
SELECT * FROM `abc2`
Havent действительно используется по умолчанию, поэтому он является новым для концепции. Обе таблицы имеют одинаковые номера столбцов и столбцов.
Я попробовал это, но не смог.
в моей модели abc
public function defaultScope() {
return array(
'alias' => 't2',
'select'=>array('t.*, t2.*'),
'union'=>array('SELECT * FROM `abc2`')
);
}
UPDATE:
Только что реализованный http://www.yiiframework.com/doc/api/1.1/CDbCriteria
, для CDbCriteria
нет NO union
.
public function defaultScope() {
return array(
//'alias' => 't',
'select'=>array('*'),
'join'=>'UNION ALL SELECT * FROM `abc2`'
);
}
код выше дает мне ошибку
CDbCommand failed to execute the SQL statement: SQLSTATE[42S22]: Column not found: 1054 Unknown column 't.make_code' in 'where clause'. The SQL statement executed was: SELECT `t`.`class_code`, `t`.`make_code`, `t`.`model_code` FROM `abc` `t` UNION ALL SELECT * FROM `abc2` WHERE `t`.`make_code`=:yp0 LIMIT 1. Bound with :yp0='11'
в обеих таблицах, у меня есть столбец make_code
Мне нужен запрос, чтобы он выглядел как
SELECT * FROM
(
SELECT * FROM `abc`
UNION ALL
SELECT * FROM `abc2`
) AS t
как это сделать?
Ответы
Ответ 1
Вы можете использовать конструктор запросов Yii ; это решение, когда вам нужно строить нестандартные запросы, и он поддерживает UNION
:
$data = Yii::app()->db->createCommand()
->select('*')
->from('abc')
->union('SELECT * FROM `abc2`')
->where('make_code=:make_code', [':make_code'=>42])
->queryAll();
В качестве альтернативы вместо прямого запроса вы можете использовать ->getText()
или написать SQL вручную, а затем использовать CSqlDataProvider
для создания настраиваемых данных источник.
Ответ 2
Здравствуйте, я надеюсь, что смогу помочь вам,
прямо сейчас cdbcriteria of yii 1.x не готов для профсоюзов... поэтому я думаю больше о других решениях или wa.
Таким образом, простой способ обойти это - создать представление из требуемого запроса:
CREATE VIEW unionAbc AS
SELECT * FROM `abc`
UNION ALL
SELECT * FROM `abc2`
то с этой точки зрения вы можете построить новую модель и вызвать ее с большим трудом.
другое решение, которое я нашел, заключается в объединении результатов запросов модели, это я говорю вам с точки зрения теории php, что я имею в виду, так это то, что когда вы создаете модельный запрос в yii, он возвращает либо массив, либо объект, вам нужно будет использовать преобразователи массива из модели, которые существуют в помощнике yii, а затем объединить оба массива, чтобы в результате появилась новая информация с информацией
Третье решение, которое не было протестировано, будет:
$dataProvider = new CArrayDataProvider('User');
$dataProvider->setData($modelabc->findAll());
$dataProvider->setData($modelabc2->findAll());
С уважением.
Ответ 3
Я предлагаю решение KISS:
возможно ли создать вид из профсоюза и работать с ним?
и затем создайте Active Record из этого представления.
Конечно, для создания/удаления данных в пользовательском интерфейсе вы должны создать модель отдельно в обеих таблицах.
<Б > Обновление
вы можете создать представление в базе данных:
CREATE VIEW abc_union AS
SELECT * FROM abc
СОЮЗ ВСЕ
SELECT * FROM abc2
а затем сгенерируйте модель с Gii для этого представления.
Ответ 4
Прежде всего, если в БД есть 2 одинаковых таблицы, возможно, лучше собрать их в один. Реализация Yii ActiveRecord на основе простого правила: одна таблица → одна активная модель записи.
Я предлагаю вам это решение с использованием шаблона репозитория. Я не думаю, что использование defaultScope()
существенно.
1.Создайте интерфейс, чтобы обе модели продуктов применяли некоторые распространенные методы.
interface Product
{
public function findAllByMakeCode($makeCode);
// other common methods here
}
2.Создайте признак с реализацией общих методов или требуемой по умолчанию областью.
trait ProductTrait
{
function findAllByMakeCode($makeCode)
{
return $this->model()->findAllByAttributes(['make_code' => $makeCode]);
}
function defaultScope()
{
// your default scope condition
// for example field is_deleted equals to 0
return ['condition' => 'is_deleted=0'];
}
// other common methods implementation
}
3.Создайте отдельные модели AR для обеих таблиц.
// used product entity
class ProductUsed extends CActiveRecord implements Product
{
use ProductTrait;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'product_used';
}
}
// new product entity
class ProductNew extends CActiveRecord implements Product
{
use ProductTrait;
public static function model($className=__CLASS__)
{
return parent::model($className);
}
public function tableName()
{
return 'product_new';
}
}
4.Создайте класс репозитория.
class ProductRepository
{
public function findAllByMakeCode($makeCode)
{
return array_merge(
ProductUsed::model()->findAllByMakeCode($makeCode),
ProductNew::model()->findAllByMakeCode($makeCode)
);
}
public function findAll($condition = '', array $params = [])
{
return array_merge(
ProductUsed::model()->findAll($condition = '', array $params = []),
ProductNew::model()->findAll($condition = '', array $params = [])
);
}
}
5. Используйте его.
$repository = new ProductRepository();
// all products
$products = $repository->findAll();
// products with 42 make code
$products42 = $repository->findAllByMakeCode(42);
Возможно, он выглядит немного сложным, но он того стоит.
Ответ 5
Вы можете сделать UNION следующим:
$firtQuery = Yii::app()->db->createCommand()
->select("*")
->from('abc')
//->where() you can add WHERE clause in here
->getText();
$result = Yii::app()->db->createCommand()
->select("*")
->from('abc2')
//->where() you can add WHERE clause in here
->union($firtQuery)
->queryRow();