来自一对多关系字段

时间:2017-04-28 09:30:23

标签: mysql activerecord yii2 query-builder

当我想从关系表字段计算时,帮助我理解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'

1 个答案:

答案 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的正确方法)