假设我有一个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();