从指向相同 table 的两个关系中过滤 first_name 和 last_name
filter first_name and last_name from two relation pointing to same table
我在 user
table 中有列 first_name
和 last_name
,这又与 order_item
table 相关 instructor_id
和 user_id
都链接到 user
table.
现在我在 OrderItem
模型中定义了如下关系:
public function getInstructor() {
return $this->hasOne(User::className(), ['id' => 'instructor_id']);
}
和
public function getCustomerName() {
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
并在 OrderSearch
模型中
public $instructor;
public $name;
$query->joinWith(['instructor','location1','customerName n']);
$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->name])
->$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->instructor]);
现在我收到类似
的错误
Method yii\db\ActiveQuery::__toString() must not throw an exception,
caught Exception: Serialization of 'Closure' is not allowed
如果我在 joinwith 中删除别名 n,我会收到如下错误:
语法错误或访问冲突:1066 不唯一 table/alias:'user'
The SQL being executed was: SELECT COUNT(*) FROM `order_item` LEFT JOIN `user` ON
`order_item`.`instructor_id` = `user`.`id` LEFT JOIN `location` ON `order_item`.`location_id` =
`location`.`id` LEFT JOIN `user` ON `order_item`.`user_id` = `user`.`id`
你可以试着做成类似这样的:
class Order {
...
//first relation with table COMPANY
public function getCustomer()
{
return $this->hasOne( Company::className(), ['id' => 'customerid'] ) //table COMPANY
->andOnCondition( [ '==relationAlias==.type' => 'customer' ] );
}
//second relation with table COMPANY
public function getSupplier()
{
return $this->hasOne( Company::className(), ['id' => 'supplierid'] ) //table COMPANY
->andOnCondition( [ '==relationAlias==.type' => 'supplier' ] );
}
...
}
然后我们可以写
$orders = Order::find()
->alias( 'o' )
->innerJoinWith('customer c')
->innerJoinWith('supplier s');
构建查询
select o.* from order o
join company c on c.id = o.customerid and c.type = 'customer'
join company s on s.id = o.supplierid and s.type = 'supplier'
这个问题是在 github 上提出的,并提供了解决方案:
https://github.com/yiisoft/yii2/issues/10883
比我想的简单多了,但是花了很多时间才解决。
但是我还是不明白为什么题中的方法不行
就像我所做的那样,我将查询分开如下,并在查询中使用了别名。
现有
$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->name])
->$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->instructor]);
已更新
$query->andFilterWhere(['like', 'concat(n.first_name," ",n.last_name)', $this->name]);
$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->instructor]);
它工作正常。
我在 user
table 中有列 first_name
和 last_name
,这又与 order_item
table 相关 instructor_id
和 user_id
都链接到 user
table.
现在我在 OrderItem
模型中定义了如下关系:
public function getInstructor() {
return $this->hasOne(User::className(), ['id' => 'instructor_id']);
}
和
public function getCustomerName() {
return $this->hasOne(User::className(), ['id' => 'user_id']);
}
并在 OrderSearch
模型中
public $instructor;
public $name;
$query->joinWith(['instructor','location1','customerName n']);
$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->name])
->$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->instructor]);
现在我收到类似
的错误Method yii\db\ActiveQuery::__toString() must not throw an exception,
caught Exception: Serialization of 'Closure' is not allowed
如果我在 joinwith 中删除别名 n,我会收到如下错误: 语法错误或访问冲突:1066 不唯一 table/alias:'user'
The SQL being executed was: SELECT COUNT(*) FROM `order_item` LEFT JOIN `user` ON
`order_item`.`instructor_id` = `user`.`id` LEFT JOIN `location` ON `order_item`.`location_id` =
`location`.`id` LEFT JOIN `user` ON `order_item`.`user_id` = `user`.`id`
你可以试着做成类似这样的:
class Order {
...
//first relation with table COMPANY
public function getCustomer()
{
return $this->hasOne( Company::className(), ['id' => 'customerid'] ) //table COMPANY
->andOnCondition( [ '==relationAlias==.type' => 'customer' ] );
}
//second relation with table COMPANY
public function getSupplier()
{
return $this->hasOne( Company::className(), ['id' => 'supplierid'] ) //table COMPANY
->andOnCondition( [ '==relationAlias==.type' => 'supplier' ] );
}
...
}
然后我们可以写
$orders = Order::find()
->alias( 'o' )
->innerJoinWith('customer c')
->innerJoinWith('supplier s');
构建查询
select o.* from order o
join company c on c.id = o.customerid and c.type = 'customer'
join company s on s.id = o.supplierid and s.type = 'supplier'
这个问题是在 github 上提出的,并提供了解决方案: https://github.com/yiisoft/yii2/issues/10883
比我想的简单多了,但是花了很多时间才解决。 但是我还是不明白为什么题中的方法不行
就像我所做的那样,我将查询分开如下,并在查询中使用了别名。
现有
$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->name])
->$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->instructor]);
已更新
$query->andFilterWhere(['like', 'concat(n.first_name," ",n.last_name)', $this->name]);
$query->andFilterWhere(['like', 'concat(user.first_name," ",user.last_name)', $this->instructor]);
它工作正常。