在同一个表上使用带有内连接的Yii2 querybuilder

时间:2015-12-04 12:50:46

标签: mysql sql yii2

我有一张包含大量日期列表的表格。

通常我使用活动记录显示日期范围内的所有列表:

return $this->hasMany(Ranking::className(), ['project_hash' => 'hash'])
        ->where(['>', 'date', date('Y-m-d', strtotime("-8 weeks"))]);  

然后输出一个表格,其中所有列表按日期排序,这是应用程序收集数据时每周一次。

我需要有一个替代视图,按月显示输出,我有一个有效的SQL查询,但我不能让它在Yii2中工作。我正在使用querybuilder,因为这似乎是构建更复杂查询的正确途径。

原始sql是:

SELECT r.*
FROM ranking AS r
JOIN (
    SELECT MAX(t.date) AS date
    FROM ranking AS t
    GROUP BY YEAR(t.date), MONTH(t.date)
    ) AS x USING (date)
where project_hash = 'TFQDaZ4CZpqvJtvF';

到目前为止,我已将此代码与querybuilder配合使用,但它会输出所有项目

$subQuery = (new \yii\db\Query())
->select(['MAX(t.date) AS date'])
->from('ranking AS t')
->groupBy(['YEAR(t.date)', 'MONTH(t.date)']);


$rows = (new \yii\db\Query())
->select(['r.*'])
->from('ranking AS r')
->innerJoin(['x' => $subQuery])
->where(['project_hash' => 'TFQDaZ4CZpqvJtvF'])
->all();
foreach ($rows as $rank) {
  echo 'key'.$rank['keyword'].' date:'.$rank['date'].'<br>';
};

生成的sql是:

SELECT `r`.* 
FROM `ranking` `r` 
INNER JOIN (
    SELECT MAX(t.date) AS date 
    FROM `ranking` `t` 
    GROUP BY YEAR(t.date), MONTH(t.date)) `x` 
WHERE `project_hash`='TFQDaZ4CZpqvJtvF'

是否可以使用querybuilder创建此查询?我尝试了不同的方法,这些方法通常会导致错误,而且我似乎无法将“AS”放在正确的位置,或者根本不会在那里获得USING条款。< / p>

感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

试试这个

$subQuery = (new \yii\db\Query())
        ->select(['MAX(t.date) AS date'])
        ->from('ranking AS t')
        ->groupBy(['YEAR(t.date)', 'MONTH(t.date)']);


    $rows = (new \yii\db\Query())
        ->select(['r.*'])
        ->from('ranking AS r')
        ->innerJoin(['x USING (date)' => $subQuery])
        ->where(['project_hash' => 'TFQDaZ4CZpqvJtvF'])
        ->createCommand()->rawSql;

它将创建Query Like

SELECT `r`.* FROM `ranking` `r` 
INNER JOIN (
 SELECT MAX(t.date) AS date 
 FROM `ranking` `t` 
 GROUP BY YEAR(t.date), MONTH(t.date)
) x USING (date) 
WHERE `project_hash`='TFQDaZ4CZpqvJtvF'