【发布时间】:2021-11-02 10:21:41
【问题描述】:
有 2 张桌子:
-
product_url (
id,product_id,url)id product_id url 1 1234 http://example.org/sku1234.html 2 1234 http://anotherdomain.com/alice-book.html 3 1234 http://bookstore.com/Alices-Adventures-in-Wonderland.html 4 4321 http://example.org/sku4321.html -
购物 (
id,url,tag)id url tag 1 http://example.org/ low 2 http://anotherdomain.com/ med 3 http://bookstore.com/ hig
(!)我从 SUBSTRING_INDEX as Array 上的两个连接表(product_url + shop)中进行 ActiveQuery 选择。
$product_url = ProductUrl::find()
->alias('pu')
->select('pu.*, tag')
->leftJoin('shop', "SUBSTRING_INDEX(pu.url, '/', 3) = SUBSTRING_INDEX(shop.url, '/', 3)")
->asArray()
->all();
并期望得到这样的数据
product_url_tag (id,product_id,url,tag)
| id | product_id | url | tag |
|----|------------|-----------------------------------------------------------|-----|
| 1 | 1234 | http://example.org/sku1234.html | low |
| 2 | 1234 | http://anotherdomain.com/alice-book.html | med |
| 3 | 1234 | http://bookstore.com/Alices-Adventures-in-Wonderland.html | hig |
| 4 | 4321 | http://example.org/sku4321.html | low |
输出为数组即可:
array(4) {
[0]=>
array(4) {
["id"] => string(1) "1"
["product_id"] => string(4) "1234"
["url"] => string(31) "http://example.org/sku1234.html"
["tag"] => string(3) "low"
}
[1]=>
array(4) {
["id"] => string(1) "2"
["product_id"] => string(4) "1234"
["url"] => string(40) "http://anotherdomain.com/alice-book.html"
["tag"] => string(3) "med"
}
[2]=>
array(4) {
["id"] => string(1) "3"
["product_id"] => string(4) "1234"
["url"] => string(57) "http://bookstore.com/Alices-Adventures-in-Wonderland.html"
["tag"] => string(3) "hig"
}
[3]=>
array(4) {
["id"] => string(1) "4"
["product_id"] => string(4) "4321"
["url"] => string(31) "http://example.org/sku4321.html"
["tag"] => string(3) "low"
}
但如果我想获得与 ActiveRecord 对象相同的数据,tag 将丢失。
$product_url = ProductUrl::find()
->alias('pu')
->select('pu.*, tag')
->leftJoin('shop', "SUBSTRING_INDEX(pu.url, '/', 3) = SUBSTRING_INDEX(shop.url, '/', 3)")
// ->asArray()
->all();
结果
array(4) {
[0]=>
object(app\models\ProductUrl)#139 (10) {
["_attributes":"yii\db\BaseActiveRecord":private]=>
array(3) {
["id"] => int(1)
["product_id"] => int(1234)
["url"] => string(31) "http://example.org/sku1234.html"
}
["_oldAttributes":"yii\db\BaseActiveRecord":private]=>
array(3) {
["id"] => int(1)
["product_id"] => int(1234)
["url"] => string(31) "http://example.org/sku1234.html"
}
["_related":"yii\db\BaseActiveRecord":private]=>
array(0) {
}
["_relationsDependencies":"yii\db\BaseActiveRecord":private]=>
array(0) {
}
["_errors":"yii\base\Model":private]=>
NULL
["_validators":"yii\base\Model":private]=>
NULL
["_scenario":"yii\base\Model":private]=>
string(7) "default"
["_events":"yii\base\Component":private]=>
array(0) {
}
["_eventWildcards":"yii\base\Component":private]=>
array(0) {
}
["_behaviors":"yii\base\Component":private]=>
array(0) {
}
}
[1]=>
object(app\models\ProductUrl)#149 (10) {
["_attributes":"yii\db\BaseActiveRecord":private]=>
array(3) {
["id"] => int(2)
["product_id"] => int(1234)
["url"] => string(40) "http://anotherdomain.com/alice-book.html"
}
["_oldAttributes":"yii\db\BaseActiveRecord":private]=>
array(3) {
["id"] => int(2)
["product_id"] => int(1234)
["url"] => string(40) "http://anotherdomain.com/alice-book.html"
}
["_related":"yii\db\BaseActiveRecord":private]=>
array(0) {
}
["_relationsDependencies":"yii\db\BaseActiveRecord":private]=>
array(0) {
}
["_errors":"yii\base\Model":private]=>
NULL
["_validators":"yii\base\Model":private]=>
NULL
["_scenario":"yii\base\Model":private]=>
string(7) "default"
["_events":"yii\base\Component":private]=>
array(0) {
}
["_eventWildcards":"yii\base\Component":private]=>
array(0) {
}
["_behaviors":"yii\base\Component":private]=>
array(0) {
}
}
[2]=>
object(app\models\ProductUrl)#150 (10) {
["_attributes":"yii\db\BaseActiveRecord":private]=>
array(3) {
["id"] => int(3)
["product_id"] => int(1234)
["url"] => string(57) "http://bookstore.com/Alices-Adventures-in-Wonderland.html"
}
["_oldAttributes":"yii\db\BaseActiveRecord":private]=>
array(3) {
["id"] => int(3)
["product_id"] => int(1234)
["url"] => string(57) "http://bookstore.com/Alices-Adventures-in-Wonderland.html"
}
["_related":"yii\db\BaseActiveRecord":private]=>
array(0) {
}
["_relationsDependencies":"yii\db\BaseActiveRecord":private]=>
array(0) {
}
["_errors":"yii\base\Model":private]=>
NULL
["_validators":"yii\base\Model":private]=>
NULL
["_scenario":"yii\base\Model":private]=>
string(7) "default"
["_events":"yii\base\Component":private]=>
array(0) {
}
["_eventWildcards":"yii\base\Component":private]=>
array(0) {
}
["_behaviors":"yii\base\Component":private]=>
array(0) {
}
}
[3]=>
object(app\models\ProductUrl)#151 (10) {
["_attributes":"yii\db\BaseActiveRecord":private]=>
array(3) {
["id"] => int(4)
["product_id"] => int(4321)
["url"] => string(31) "http://example.org/sku4321.html"
}
["_oldAttributes":"yii\db\BaseActiveRecord":private]=>
array(3) {
["id"] => int(4)
["product_id"] => int(4321)
["url"] => string(31) "http://example.org/sku4321.html"
}
["_related":"yii\db\BaseActiveRecord":private]=>
array(0) {
}
["_relationsDependencies":"yii\db\BaseActiveRecord":private]=>
array(0) {
}
["_errors":"yii\base\Model":private]=>
NULL
["_validators":"yii\base\Model":private]=>
NULL
["_scenario":"yii\base\Model":private]=>
string(7) "default"
["_events":"yii\base\Component":private]=>
array(0) {
}
["_eventWildcards":"yii\base\Component":private]=>
array(0) {
}
["_behaviors":"yii\base\Component":private]=>
array(0) {
}
}
为什么tag 输了?以及如何从加入的shop 中获取tag 作为 ActiveRecord 对象?
更新:
./models/Shop.php
namespace app\models;
use Yii;
/**
* This is the model class for table "shop".
*
* @property int $id
* @property string $url
* @property string $tag
*/
...
./models/ProductUrl.php
namespace app\models;
use Yii;
/**
* This is the model class for table "product_url".
*
* @property int $id
* @property int $product_id
* @property string $url
*
* @property Product $product
* @property Shop $shop
*/
...
/**
* @return \yii\db\ActiveQuery
*/
public function getShop()
{
return $this->hasOne(Shop::className(), ["SUBSTRING_INDEX(url,'/',3)" => "SUBSTRING_INDEX(url,'/',3)"]);
}
./controllers/ProductController.php
namespace app\controllers;
use Yii;
use app\models\ProductUrl;
use app\models\Shop;
...
【问题讨论】:
-
这能回答你的问题吗? Subquery in SELECT using Yii2 ActiveRecord
-
@rob006 不,因为我在模型中有 $tag 属性。
-
我很确定你没有,因为 var_dump 没有在
ProductUrl中显示tag属性,并且您粘贴的代码中没有 sn-p 证明此属性的存在。 -
您的
->all()调用返回ProductUrl实例的数组。如果ProductUrl没有tag属性,那么Yii 无法存储tag列以供查询并简单地删除它。这就是为什么你需要明确定义ProductUrl::$tag。 -
你也可以使用关系,但是
$this->hasOne()中的["SUBSTRING_INDEX(url,'/',3)" => "SUBSTRING_INDEX(url,'/',3)"]是不正确的——这些必须是列,因为 Yii 将使用它们来映射对象。如果你以这种方式使用表达式是不可能的。
标签: php activerecord yii yii2