我有一个执行所需操作的查询
SELECT v.* FROM vehicle v
WHERE v.company_id = 2 AND v.id NOT IN
(
SELECT h.vehicle_id
FROM hire h
WHERE
h.start_date is not null and h.end_date is null
)
所以现在我想在Symfony / Doctrine
中编写这个查询我有这个
$qb = $this->_em->createQueryBuilder();
$subq = $this->_em->createQueryBuilder();
$subq ->select('h.vehicle')
->from('AppBundle\Entity\Hire', 'h')
->andWhere('h.startDate is not null and h.endDate is null');
$qb->select('v')
->from('AppBundle\Entity\Vehicle', 'v')
->where($qb->expr()->notIn('v.id',$subq->getDQL()))
->andWhere('v.company = :company')
->setParameter('company', $company)
->orderBy('v.registrationNumber', 'ASC')
;
$t = $qb->getDQL();
return $qb;
如你所见,我试图转储DQL,看看是否给了我任何线索,这是
SELECT v
FROM AppBundle\Entity\Vehicle v
WHERE (v.id NOT IN(SELECT h.vehicle FROM AppBundle\Entity\Hire h WHERE h.startDate is not null and h.endDate is null))
AND v.company = :company
ORDER BY v.registrationNumber ASC
我尝试将其转换回简单的SQL,即删除AppBundle并将列名转换回实际的列名,然后运行并获得正确的结果。
但我收到此错误
学说\ ORM \查询\ QueryException: [语义错误]第0行,第69行附近'车辆FROM':错误:无效的PathExpression。必须是StateFieldPathExpression。
在vendor \ doctrine \ orm \ lib \ Doctrine \ ORM \ Query \ QueryException.php:63 在Doctrine \ ORM \ Query \ QueryException :: semanticalError('第0行,第69行附近\' vehicle FROM \':错误:无效的PathExpression。必须是StateFieldPathExpression。',对象(QueryException))
涉及的2个表是
CREATE TABLE `hire` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) DEFAULT NULL,
`driver_id` int(11) DEFAULT NULL,
`vehicle_id` int(11) DEFAULT NULL,
`corporate_hire` tinyint(1) DEFAULT NULL,
`end_date` datetime DEFAULT NULL,
`end_miles` decimal(10,1) DEFAULT NULL,
`start_date` datetime DEFAULT NULL,
`start_miles` decimal(10,1) DEFAULT NULL,
`created_by` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`updated_by` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`deleted_by` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `IDX_B8017EFC979B1AD6` (`company_id`),
KEY `IDX_B8017EFCC3423909` (`driver_id`),
KEY `IDX_B8017EFC545317D1` (`vehicle_id`),
CONSTRAINT `FK_B8017EFC545317D1` FOREIGN KEY (`vehicle_id`) REFERENCES `vehicle` (`id`) ON DELETE SET NULL,
CONSTRAINT `FK_B8017EFC979B1AD6` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) ON DELETE SET NULL,
CONSTRAINT `FK_B8017EFCC3423909` FOREIGN KEY (`driver_id`) REFERENCES `driver` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB AUTO_INCREMENT=29 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
和
CREATE TABLE `vehicle` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`company_id` int(11) DEFAULT NULL,
`storage_id` int(11) DEFAULT NULL,
`created_by` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`updated_by` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`deleted_by` varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
`deleted_at` datetime DEFAULT NULL,
`created_at` datetime DEFAULT NULL,
`updated_at` datetime DEFAULT NULL,
`date_of_manufacture` datetime DEFAULT NULL,
`engine_size` int(11) DEFAULT NULL,
`make` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`model` varchar(50) COLLATE utf8_unicode_ci DEFAULT NULL,
`registration_number` varchar(10) COLLATE utf8_unicode_ci NOT NULL,
`vin` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `IDX_1B80E486979B1AD6` (`company_id`),
KEY `IDX_1B80E4865CC5DB90` (`storage_id`),
CONSTRAINT `FK_1B80E4865CC5DB90` FOREIGN KEY (`storage_id`) REFERENCES `storage` (`id`) ON DELETE SET NULL,
CONSTRAINT `FK_1B80E486979B1AD6` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB AUTO_INCREMENT=25 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
我不确定Invalid Path Expression
应该让我将其视为实际错误。
FIX:只是像这样添加IDENTITY()
$subq ->select('IDENTITY(h.vehicle)')
答案 0 :(得分:2)
为我们工作的是(适合您的示例,因此未经测试):
$subQuery->select('IDENTITY(h.vehicle)');
$subQuery->from('AppBundle\Entity\Hire', 'h');
$dqlString = $subQuery->getQuery()->getDQL();
$query->andWhere('v.id' 'NOT IN (' . $dqlString . ')');
我看到的唯一两个不同之处是:
所以我的假设是你的$subq ->select('h.vehicle')
没有返回 id ,可以在主查询的NOT IN条件中使用,这可能会被你解决DQL SELECT v
:这将返回所有字段,但您只需要 v.id 。