gpt4 book ai didi

mysql - Doctrine2 DBAL 存在查询

转载 作者:行者123 更新时间:2023-12-02 04:02:40 25 4
gpt4 key购买 nike

我想请求您帮助 Doctrine2 DBAL使用 QueryBuilder 构建的查询。我已经习惯了 ORM,但我认为对于在监听器中调用的此类查询来说,这是一种矫枉过正的做法。

我需要使用 SELECT EXISTS 进行查询我不知道如何使用 DBAL QueryBuilder 构建它.

我已经创建了一个子查询:

$subQuery = $connection->createQueryBuilder();
$subQuery
->select('o.id')
->from('order', 'o')
->leftJoin('o', 'payment', 'p')
->where($subQuery->expr()->isNull('p.id'))
;

我主要是想检查是否有未付款的订单。我现在不知道如何构建 SELECT EXISTS询问?有人能指出我正确的方向吗?我在想这样的事情:

$qb->select('EXISTS(?)')->setParameter($subQuery->getDQL())

这是正确的解决方案吗?

@编辑

经过一段时间的思考,我决定使用 ORM。不幸的是,这也不起作用,我收到一个错误:

line 0, col 7: Error: Expected known function, got 'EXISTS'

DQL 是: SELECT EXISTS(<subquery here>)

考虑到它是用 QueryBuilder 构建的,这有点奇怪:

/* @var $qb QueryBuilder */
$qb = $this->em->createQueryBuilder();
$qb
->select($qb->expr()->exists($subQuery->getDQL()));

最佳答案

晚了几年,但您需要在 QueryBuilder 的 SELECTWHERE 语句部分中指定 EXISTS 子查询 SQL,如下所示反对使用参数。

此外,由于 order 是 MySQL 中的保留字,因此您需要使用标识符引号 `(反引号)来转义表名称。

使用 ORM 时;您必须指定引用实体的 FROM 语句,因此您需要更改方法。

$connection = $this->em->getConnection();
$expr = $connection->getExpressionBuilder();
$qbSub = $connection->createQueryBuilder()
->select('1')
->from('`order`', 'o')
->leftJoin('o', '`payment`', 'p', $expr->eq('p.order_id', 'o.id'))
->where($expr->isNull('p.id'));

/**
* @return string "1" if a record exists, "0" otherwise
*/
$connection->createQueryBuilder()
->select('EXISTS(' . $qbSub->getSQL() . ')')
->execute()
->fetchColumn();

生成的 SQL

SELECT EXISTS(
SELECT 1
FROM `order` AS o
LEFT JOIN `payment` AS p
ON p.order_id = o.id
WHERE p.id IS NULL
);

Note: If you have any parameters, the values for the placeholders must be bound using QueryBuilder::setParameter() on the top-levelquery, not the sub-queries.

$qbSub = $connection->createQueryBuilder()
->select('1')
->from('`order`', 'o')
->leftJoin('o', '`payment`', 'p', $expr->andX(
$expr->eq('p.order_id', 'o.id'),
$expr->eq('p.name', ':name') // subquery placeholder
))
->where($expr->isNull('p.id'));

$connection->createQueryBuilder()
->select('EXISTS(' . $qbSub->getSQL() . ')')
->setParameter('name', $value) // subquery placeholder param value
->execute()
->fetchColumn();

但是,我建议将查询从排除联接更改为包含 NOT EXISTS 的包含联接。这样做将从结果集中过滤掉已付款的订单。而不是尝试加入每次付款的每个订单并检索返回 null 的付款。显着提高查询性能。

示例 db-fiddle

SELECT EXISTS (
SELECT 1
FROM `order` AS o
WHERE NOT EXISTS(
SELECT NULL
FROM `payment` AS p
WHERE p.order_id = o.id
)
)

关于mysql - Doctrine2 DBAL 存在查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41140768/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com