如何在 Yii2 中创建复杂的左外连接?

Posted

技术标签:

【中文标题】如何在 Yii2 中创建复杂的左外连接?【英文标题】:How do I create a complex left outer join in Yii2? 【发布时间】:2015-06-19 01:54:21 【问题描述】:

如何在 Yii2 中执行这个查询?

SELECT `keyword`.`id`, `keyword`, `volume`, `cpc`, `competition`, `keyword_id` 
FROM `keyword` 
LEFT JOIN `ad_group_keyword` 
  ON keyword.id = ad_group_keyword.keyword_id 
  and ad_group_id = 1 
WHERE ((`keyword_id` IS NULL) 
  AND (NOT (`volume` IS NULL))) 
  AND (NOT (`cpc` IS NULL)) 
ORDER BY volume desc 
LIMIT 1;

我尝试了以下和许多组合,但我无法正确使用 ON 部分。

$kw = Keyword::find()->select(['keyword.id', 'keyword', 'volume', 'cpc', 'competition', 'keyword_id'])->
  leftJoin('ad_group_keyword', 'keyword.id = ad_group_keyword.keyword_id', ['ad_group_id'=>1])->
  andWhere(['keyword_id'=>null])->
  andWhere(['not', ['volume' => null]])->andWhere(['not', ['cpc' => null]])->
  orderBy('volume desc')->asArray()->limit(1)->all();

上面生成这个SQL,缺少ON的第二个条件:

SELECT keyword.id, keyword, volume, cpc, competition, keyword_id FROM keyword LEFT JOIN ad_group_keyword ONkeyword.id = ad_group_key (keyword_id IS NULL) AND (NOT (volume IS NULL))) AND (NOT (cpc IS NULL)) ORDER BY volume desc LIMIT 1

我也试过了

leftJoin('ad_group_keyword', ['keyword.id'=>'keyword_id', 'ad_group_id'=>1])->

但它会生成

FROM keyword LEFT JOIN ad_group_keyword ON (keyword.id='keyword_id') AND (ad_group_id=1)

'keyword_id'在引号中,所以它把它当作一个字符串!

文档:http://www.yiiframework.com/doc-2.0/yii-db-query.html#leftJoin()-detail

(这就是我讨厌处理 ORM API 的原因。我把所有的时间都花在了精通 SQL 上。现在你让我学会了一种全新的方法来做同样的事情,有时这是不可能的。)

【问题讨论】:

【参考方案1】:

关于您必须处理 ORM API 的评论,您可以使用 createCommand 方法。您可以使用此方法使用原始 sql 查询。不同之处在于您不会得到ActiveRecord[],而只会得到array[](这通常适用于复杂的查询)。

$sql = "SELECT `keyword`.`id`, `keyword`, `volume`, `cpc`, `competition`, `keyword_id` 
FROM `keyword` 
LEFT JOIN `ad_group_keyword` 
  ON keyword.id = ad_group_keyword.keyword_id 
  and ad_group_id = 1 
WHERE ((`keyword_id` IS NULL) 
  AND (NOT (`volume` IS NULL))) 
  AND (NOT (`cpc` IS NULL)) 
ORDER BY volume desc 
LIMIT 1;";

$params = [];

$kw = Yii::$app->db->createCommand($sql, $params)->queryAll();

【讨论】:

【参考方案2】:
leftJoin('ad_group_keyword', ['and', 'keyword.id = keyword_id', "ad_group_id = $adGroupId"])->

【讨论】:

以上是关于如何在 Yii2 中创建复杂的左外连接?的主要内容,如果未能解决你的问题,请参考以下文章

真正的左外连接

linq中的左外连接

LINQ查询中的左外连接[重复]

如何使用 linq lambda 扩展方法执行带有 where 子句的左外连接

如何在雪花的左外连接期间提取所有值(即使是那些不匹配的值)?

LINQ:具有多个条件的左外连接