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();