使用“ Doctrine查询”构建器从子查询中选择

时间:2020-11-11 20:57:27

标签: php mysql doctrine-orm doctrine

假设我有一个entries表,看起来像这样:

| id | category | text | user_id |
|----|----------|------|---------|
| 1  | A        | z    | 22      |
| 2  | B        | y    | 23      |
| 3  | B        | x    | 24      |
| 4  | C        | w    | 25      |

我想获取具有最高ID的指定类别的行。因此,在此示例中,如果我搜索类别B,则希望它返回3,B,x,24

表中还有其他几列,为简洁起见,仅显示了这三列。存在其他必须连接的列,例如获取用户信息。

我有以下查询有效:

SELECT *
FROM (
         SELECT MAX(id) as id
         FROM entries
         WHERE category = 'B'
         GROUP BY category
     ) as tmp
         LEFT JOIN entries e ON e.id = tmp.id
         LEFT JOIN users u ON (e.user_id = u.id)

我不确定如何将其转换为DQL,特别是使用查询生成器,因为要添加的多个条件我不想使用串联来构建DQL字符串。我正在与此:

$subquery = $entityManager
    ->getRepository(Entry::class)
    ->createQueryBuilder('entryIds')
    ->select('MAX(entryIds.id)'
    ->orWhere("entryIds.category = ?0")
    ->groupBy('entryIds.category')
    ->getDQL();

$rows = $entityManager
    ->getRepository(Entry::class)
    ->createQueryBuilder('entry')
    ->select('entry, user')
    ->from("($subquery)", 'tmp')
    ->leftJoin(User::class, 'user', Join::WITH, 'entry.user = user.id')
    ->setParameter(0, 'B')
    ->getQuery()
    ->execute();

我收到此错误:

[Semantical Error] line 0, col 453 near ', (SELECT MAX(entryIds.id)': Error: Subquery is not supported here

查询生成器从上面生成此DQL:

SELECT entry, user
FROM Namespace\\Entry entry
LEFT JOIN Namespace\\User user WITH entry.user = user.id,
(SELECT MAX(entryIds.id) FROM Namespace\\Entry entryIds WHERE entryIds.category = ?0 GROUP BY entryIds.category) tmp

所以看起来我没有将子查询放在正确的位置;我在哪里可以确保基础选择查询子查询,然后联接其他表?


编辑:我设法使其与WHERE ANY一起使用,但查询速度慢了4.5倍:

$subquery = $entityManager
    ->getRepository(Entry::class)
    ->createQueryBuilder('entryIds')
    ->select('MAX(entryIds.id)')
    ->orWhere('entryIds.sourceSystem = ?0')
    ->groupBy('entryIds.sourceSystem, entryIds.secondaryId')
    ->getDQL();

$qb = $entityManager
    ->getRepository(Entry::class)
    ->createQueryBuilder('entry');
$qb
    ->select('entry, user')
    ->leftJoin(User::class, 'user', Join::WITH, 'entry.user = user.id')
    ->setParameter(0, 'B')
    ->where(
        $qb->expr()->eq('entry.id', $qb->expr()->any($subquery))
    )
    ->getQuery()
    ->execute();

0 个答案:

没有答案