【问题标题】:How to use subquery in the join function of Yii framework 2 ActiveRecord?Yii框架2 ActiveRecord的join函数中如何使用子查询?
【发布时间】:2017-05-07 21:16:36
【问题描述】:

下面是我的纯 SQL 查询。

SELECT  a.*, b.*
FROM a 
INNER JOIN b 
ON a.id = b.a_id
INNER JOIN (
    SELECT a_id, MAX(add_time) AS max_add_time 
    FROM b 
    GROUP BY a_id
) m 
ON b.a_id = m.a_id AND b.add_time = m.max_add_time 
ORDER BY b.add_time DESC

我在第二个INNER JOIN 中有子查询。在我的活动查询下方。

$subQuery = B::find()->select(['a_id', 'MAX(add_time) AS max_add_time'])->groupBy('a_id');

$query = A::find()->innerJoin('b', 'a.id = b.a_id')
                  ->innerJoin('(' . 
                      $subQuery->prepare(Yii::$app->db->queryBuilder)
                               ->createCommand()
                               ->rawSql
                  . ') m', 'b.a_id = m.a_id AND a.add_time = m.max_add_time ')
                  ->orderBy('b.add_time DESC');

它工作正常,但我不喜欢我在第二个INNER JOIN 中使用子查询的方式。我想用这个查询来选择左表内连接和右表,按a_id分组,按右表的add_time(DESC)排序。我应该如何更好地使用第二个 INNER JOIN 中的子查询?

【问题讨论】:

    标签: sql yii2 subquery inner-join


    【解决方案1】:

    下面的 sn-p 未经测试,但应该是这样的。如果您阅读文档(http://www.yiiframework.com/doc-2.0/yii-db-query.html#innerJoin()-detail),您可以看到带有子查询的数组也是有效输入,键是别名。

    $subQuery = B::find()
        ->select(['a_id', 'MAX(add_time) AS max_add_time'])
        ->groupBy('a_id');
    
    $query = A::find()
        ->innerJoin('b', 'a.id = b.a_id')
        ->innerJoin(['m' => $subQuery], 'b.a_id = m.a_id AND a.add_time = m.max_add_time')
        ->orderBy('b.add_time DESC');
    

    【讨论】:

    • 非常感谢兄弟。过去一个月我一直在受苦,终于找到了这个解决方案。
    • 谢谢!快速说明,在第二个内部连接条件中应该是 ... AND b.add_time = ...
    【解决方案2】:

    创建连接后,如果需要使用子查询返回的任何列,则需要在 Yii2 模型类中添加属性,例如

    $subQuery = FinancialTransaction::find()
        ->select( new \yii\db\Expression( 'SUM(amount) as owing') )
        ->addSelect('booking_id')
        ->groupBy('booking_id');
    $query = $query
        ->addSelect(['b.*', 'owing'])
        ->leftJoin(['ft' => $subQuery], 'b.booking_display_id = ft.booking_id');
    

    要访问“欠”,模型必须具有属性(PHPdoc 可选):

    /**
     * @var float
     */
    public $owing=0;
    

    【讨论】:

      猜你喜欢
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多