Yii2:如何使用联合查询和排序创建ActiveDataProvider?

O C*_*nor 6 php sql union gridview yii2

使用Yii framework 2.0,我有两个数据库表如下.

A table:
   a_id = 1, name = yes, number = 123
   a_id = 2, name = no, number = 456 
   a_id = 3, name = ok,  number = 683

B table:
  id = 1, a_id = 1, firstname = s
  id = 2, a_id = 1, firstname = y
  id = 3, a_id = 2, firstname = e
  id = 4, a_id = 2, firstname = x
  id = 5, a_id = 2, firstname = t
  id = 6, a_id = 3, firstname = r
Run Code Online (Sandbox Code Playgroud)

我想使用ActiveDataProvider为GridView查询这些记录,结果如下.

a_id = 1, name = yes, number = 123
a_id = 1, name = s, number = null
a_id = 1, name = y, number = null
a_id = 2, name = no, number = 456
a_id = 2, name = e, number = null
a_id = 2, name = x, number = null
a_id = 2, name = t, number = null
a_id = 3, name = ok,  number = 683
a_id = 3, name = r, number = null
Run Code Online (Sandbox Code Playgroud)

下面是我工作的纯SQL查询.

SELECT `a_id`, `name`, `number` FROM `user` WHERE number != ''
UNION ALL
SELECT `a_id`, `firstname` as name , null as `number` FROM `customer` 
WHERE `firstname` != ''
ORDER BY `a_id` ASC, name ASC 
Run Code Online (Sandbox Code Playgroud)

我想用ActiveDataProvider实现上面的查询.我怎样才能做到这一点?

rob*_*sch 12

我没有测试过.但它应该像这样工作,我想:

$query1 = (new \yii\db\Query())
    ->select("a_id, name, number")
    ->from('user')
    ->where(['!=', 'number', '']);

$query2 = (new \yii\db\Query())
    ->select("a_id, firstname as name , null as number")
    ->from('customer')
    ->where(['!=', 'firstname', '']);

$unionQuery = (new \yii\db\Query())
    ->from(['dummy_name' => $query1->union($query2)])
    ->orderBy(['a_id' => SORT_ASC, 'name' => SORT_ASC]);

$provider = new ActiveDataProvider([
    'query' => $unionQuery,
    'pagination' => [
        'pageSize' => 20,
    ],
]);

$rows = $provider->getModels();
Run Code Online (Sandbox Code Playgroud)

它应该创建一个如下所示的查询:

SELECT * FROM 
(
    (SELECT `a_id`, `name`, `number` FROM `user` WHERE `number` != ''   )
    UNION 
    (SELECT `a_id`, `firstname` AS `name`, `null` AS `number` FROM `customer` WHERE `firstname` != '')
) `dummy_name`
ORDER BY `a_id`, `name`
Run Code Online (Sandbox Code Playgroud)

它的灵感来自Yii指南中的这个例子.


小智 5

以下代码在我的模型“CoinsHistorySearch.php”中进行了测试,希望对一些人有所帮助:

$queryHistory = CoinsHistory::find();
$queryHistoryRecent = CoinsHistoryRecent::find();
$query = (new ActiveQuery(CoinsHistory::className()))->from([
    'union_history' => $queryHistory->union($queryHistoryRecent)
]);

$dataProvider = new ActiveDataProvider([
    'query' => $query,
    'sort' => ['defaultOrder' => ['id' => SORT_DESC]]
]);

$filter = [];
$queryHistory->andFilterWhere($filter);
$queryHistoryRecent->andFilterWhere($filter);
Run Code Online (Sandbox Code Playgroud)