leftJoin Yii2和Raw SQL之间的区别

时间:2017-06-28 05:05:07

标签: sql activerecord yii2

我想在我的代码中使用左连接,当我使用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]);

2 个答案:

答案 0 :(得分:2)

如果我说得对,那就意味着你要对要执行的同一个查询有两个表示..前一个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>

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

答案 1 :(得分:2)

您的两个查询不一样

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

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

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

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

但是请记住,使用leftjoin中的conidtion作为内连接...

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

$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 ')