Php 聚合数据组作为Yii2关系
在我的Php 聚合数据组作为Yii2关系,php,mysql,yii2,Php,Mysql,Yii2,在我的产品模型中,我有以下两种方法:getOrderFeedback()是一种正常关系,返回一个ActiveQuery和GetTotalAveFeedback(),它返回一个给定产品记录的聚合数据数组 /** * @return \yii\db\ActiveQuery */ public function getOrderFeedback() { return $this->hasMany(OrderFeedback::className(), ['productID' =&g
产品
模型中,我有以下两种方法:getOrderFeedback()
是一种正常关系,返回一个ActiveQuery
和GetTotalAveFeedback()
,它返回一个给定产品
记录的聚合数据数组
/**
* @return \yii\db\ActiveQuery
*/
public function getOrderFeedback()
{
return $this->hasMany(OrderFeedback::className(), ['productID' => 'ID']);
}
/**
* @return array
*/
public function getTotalAndAveFeedback()
{
return $this->getOrderFeedback()
->select(['COUNT(*) AS num',
'AVG(rating) AS avg',
'FLOOR(AVG(rating)) AS full',
'MOD(AVG(rating), 1) AS decimal_portion',
'5 - FLOOR(AVG(rating)) - CEILING(MOD(AVG(rating),1)) AS empty'])->one();
}
当我有一组产品
并对其进行迭代以收集单个产品
的总计和动态反馈时,ActiveQuery
被触发,从而导致从数据库读取惰性样式。类似于下面的内容
$my_products = Product::find()->with(['supplier', 'location'])
->where(['published' => 1])
->all();
# SELECT * FROM product WHERE published = 1;
# Find all products
# SELECT * FROM supplier WHERE ID IN (s1, s2, s3);
# Eagerly load supplier
# SELECT * FROM location WHERE ID IN (l1, l2, l3, l4);
# Eagerly load location
foreach ($my_products as $product) {
echo $product->supplier->supplier_name;
# supplier object available from eager loading
echo $product->location->title;
# location object available from eager loading
echo $product->totalAndAveFeedback->decimal_portion;
# requires db access to 'lazy load' data for each product record
# SELECT COUNT(*) AS num, AVG(rating) AS avg, FLOOR(AVG(rating)) AS full, MOD(AVG(rating), 1) AS decimal_portion, 5 - FLOOR(AVG(rating)) - CEILING(MOD(AVG(rating),1)) AS empty FROM `order_feedback` WHERE `productID`=pID
}
有没有一种方法可以将getTotalAveefeedback()
视为允许使用joinWith()
/with()的关系
在产品上
ActiveQuery
以便可以急切地为每个产品
加载数据,并以与供应商
或位置
关系相同的方式提供数据
我已尝试在getTotalAveFeedback()
中删除对one()
的调用,以允许将该方法视为关系,但是产品
记录的total和vefeedback
属性都是空数组,我希望在这些数组中有一个具有decimal\u部分
等属性的对象,就好像我调用了一个简单的关系,如Supplier
这在Yii2中可能吗
/**
* @return \yii\db\ActiveQuery
*/
public function getTotalAndAveFeedback()
{
return $this->getOrderFeedback()
->select(['productID', 'COUNT(*) AS num',
'AVG(rating) AS avg',
'FLOOR(AVG(rating)) AS full',
'MOD(AVG(rating), 1) AS decimal_portion',
'5 - FLOOR(AVG(rating)) - CEILING(MOD(AVG(rating),1)) AS empty'])
->groupBy(['productID']);
}
正如@Pa3Py6aka所指出的,加入关系时数组为空的原因是没有选择productID
,返回的OrderFeedback
s与产品之间没有链接
通过将groupBy(['productID'])
方法调用添加到ActiveQuery
每个OrderFeedbacks
中,每个Product
对象都急切地加载和访问OrderFeedbacks
正如@Pa3Py6aka所指出的,加入关系时数组为空的原因是没有选择productID
,返回的OrderFeedback
s与产品之间没有链接
通过将groupBy(['productID'])
方法调用添加到ActiveQuery
中,每个OrderFeedbacks
对象都可以急切地加载并访问productID
对象。如果在gettotalandaveffeedback()
方法中添加productID
列以选择数组,就可以了。但在即时加载中,您将有如下查询:选择COUNT(*)作为num,选择AVG(rating)作为AVG,选择FLOOR(AVG(rating))作为full,选择MOD(AVG(rating),选择1)作为十进制部分,选择5-FLOOR(AVG(rating))-选择天花(MOD(AVG(rating),选择1))作为order\u反馈中的空,其中productID位于(1,2,3…100)
,所以,如果您在getTotalAveFeedback()
方法中附加productID
列以选择数组,则此查询的结果将不是您想要的结果。但在即时加载中,您将有如下查询:从订单反馈中选择COUNT(*)作为num,AVG(rating)作为AVG,FLOOR(AVG(rating))作为full,MOD(AVG(rating),1)作为小数部分,5-FLOOR(AVG(rating))-天花(MOD(AVG(rating),1)作为空,其中productID位于(1,2,3…100)
,所以此查询的结果将不是您想要的结果