我想在我的代码中使用左连接,当我使用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]);
答案 0 :(得分:2)
如果我说得对,那就意味着你要对要执行的同一个查询有两个表示..前一个RAW查询会给你想要的结果,而不是Yii2式查询。
简单地分析您的查询我注意到前一个查询中的WHERE子句不完整(您没有传递ID参数),因此它不会按tour_package.id
属性进行过滤,并且您获得的行数超出预期..
无论如何,如果不是这样,您可以通过调用
轻松检查从Yii2QueryBuilder
生成的查询类型
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 ')