【问题标题】:difference between leftJoin Yii2 and Raw SQLleftJoin Yii2 和 Raw SQL 的区别
【发布时间】:2017-06-28 05:05:06
【问题描述】:

我想在我的代码中使用左连接,当我使用 Yii2 左连接时,代码的结果不正确,它会删除一些记录,但是当我使用带有给定命令的 Raw SQL 左连接时,结果是正确的:

sql :(没错)

SELECT tour_date.id as tdid,tour.*, tour_package.*, tour_package.id AS tpid       
FROM tour_date 
LEFT JOIN tour_package ON tour_date.tour_id=tour_package.tour_id 
LEFT JOIN tour ON tour.id=tour_package.tour_id
WHERE tour_package.id

yii2 查询:(错了)

$tourQuery = TourDate::find()
        ->select(['tour_date.id as tdid','tour.*', 'tour_package.*', 'tour_package.id AS tpid'])
        ->leftJoin(TourPackage::tableName(), 'tour_date.tour_id=tour_package.tour_id')
        ->leftJoin(Tour::tableName(), 'tour.id=tour_package.tour_id')
        ->where(['tour_package.id' => $tourPackageId]);

【问题讨论】:

标签: sql activerecord yii2


【解决方案1】:

如果我没听错,你的意思是你有两个表示你想执行的同一个查询。前一个 RAW 查询给你想要的结果,而 Yii2 样式的查询没有。

简单分析您的查询,我注意到前一个查询中的 WHERE 子句不完整(您没有传递 ID 参数),因此它不会按 tour_package.id 属性过滤,并且您获得的行数比预期的要多..

无论如何,如果不是这样,您可以通过调用轻松检查从 Yii2 QueryBuilder 生成的查询类型

echo $tourQuery->createCommand()->rawSql;

所以它会给你以下结果:

SELECT
  `tour_date`.`id` AS `tdid`, `tour`.*, `tour_package`.*, `tour_package`.`id` AS `tpid`
FROM `tour_date`
  LEFT JOIN `tour_package` ON tour_date.tour_id = tour_package.tour_id
  LEFT JOIN `tour` ON tour.id = tour_package.tour_id
WHERE `tour_package`.`id` = <your_id>

..将此与您的原始查询进行比较,您会找到答案

【讨论】:

  • 关于我们的答案,问题不在于原始 sql 中的“位置”结果是 20 条记录,但在活动记录中 yii2 是 12 ,它可以与查询生成器一起正常工作,我认为活动记录有选项可以正确工作,我不知道,关于 ActiveRecord,当 tour_date 从 tour_package 有更多记录时,它作为匹配 tour_package 计数返回,但在这里我们希望 tour_package 保留所有记录,但左连接不起作用这种情况
【解决方案2】:

你的两个查询不一样

在 RAW sql(第一个)中,您有 WHERE tour_package.id 其中 tour_package.id 没有条件。

在 Yii2 ActiveQuery sintax(第二个查询)中,您有 -&gt;where(['tour_package.id' =&gt; $tourPackageId]); 其中 tour_package.id 必须等于 $tourPackageId。

所以这两个查询返回不同的结果,因为是不同的查询..

假设 $tourPackageId 的值为 1 你至少应该使用WHERE tour_package.id = 1

但是请记住,在 leftjoin 中使用 where 条件作为内部连接 ​​..

因此,为了正确使用左连接中的 where,您应该使用左连接条件中的条件,而不是显式的 where

$tourQuery = TourDate::find()
    ->select(['tour_date.id as tdid','tour.*', 'tour_package.*', 'tour_package.id AS tpid'])
    ->leftJoin(TourPackage::tableName(), 'tour_date.tour_id=tour_package.tour_id  
              and tour_package.id = ' . $tourPackageId)
    ->leftJoin(Tour::tableName(), 'tour.id=tour_package.tour_id ')

【讨论】:

  • tanx 关于我们的答案,问题不在于原始 sql 中的“位置”结果是 20 条记录,但在活动记录中 yii2 是 12 ,它可以与查询生成器一起正常工作,我认为活动记录有选项可以正确工作,我不知道,关于 ActiveRecord,当 tour_date 从 tour_package 有更多记录时,它作为匹配 tour_package 计数返回,但在这里我们希望 tour_package 保留所有记录,但左连接不起作用这种情况
  • 请记住,在左连接中使用 where 作为内连接 .. 我已经用活动查询代码更新了答案 ..
猜你喜欢
  • 2017-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 2017-01-30
  • 1970-01-01
  • 2014-12-30
相关资源
最近更新 更多