当我想从关系表字段计算时,帮助我理解sum函数的工作原理。
查询非常简单。我有unitsOrdered表和unitsSent表。关系是1-n。所以我想计算特定订单的所有已发送单位。在此示例中,订单为id=2
;
在我的数据库中,我有数据。
unitsOrdered:
id
1
2
unitsSent:
id | order_id | units
1 | 1 | 5
2 | 2 | 2
我的查询是:
query = OrderedUnits::find()
->select([
'ou.*',
'sum(us.units) as alreadySent'
])
->joinWith('unitsSent us')
->where(['ou.id' => 2])
->orderBy('ou.id desc')
->groupBy(['ou.id'])
->all();
结果应该很清楚:
id 2 = 2 units
但是,我的查询返回:
id 2 = 10 units.
据我所知,我所做的是5 * 2 = 10;
我的查询有什么问题?
关系定义如下:
/**
* @return \yii\db\ActiveQuery
*/
public function getUnitsSent()
{
return $this->hasMany(UnitsSent::className(), ['order_id' => 'id'])
->from(['us' => UnitsSent::tableName()]);
}
实际查询:
'SELECT `ou`.*, sum(us.sent_units) as alreadySent FROM `ordered_units` `ou`
LEFT JOIN `units_sent` `us` ON `ou`.`id` = `us`.`order_id`
WHERE (`ou`.`id`= 2)
GROUP BY `ou`.`id`
ORDER BY `ou`.`id` DESC'
答案 0 :(得分:0)
您应该以这种方式使用哈希过滤器格式->where(['us.id' => 2])
并且对于获得结果2,你需要innerJoin(你的原始sql显示你有一个左连接)否则也会加入不匹配的行
query = OrderedUnits::find()
->select([
'ou.*',
'sum(us.units) as alreadySent'
])
->innerJoinWith('unitsSent us')
->where(['us.id' => 2])
->orderBy('ou.id desc')
->groupBy(['ou.id'])
->all();
并尝试检查使用
执行的实际查询echo $query->createCommand()->getRawSql();
并记住,在mysql的5.7版本中不允许选择未聚合且未在group by中提及的列(并且无论如何不是在SQL中使用group by的正确方法)