Tôi đã tìm ra giải pháp bằng cách điều chỉnh ví dụ DQL này tới DBAL. Bí quyết là lấy SQL thô của truy vấn con, đặt nó trong dấu ngoặc và nối nó. Các tham số được sử dụng trong truy vấn phụ phải được đặt trong truy vấn chính:
$subSelect = $connection->createQueryBuilder()
->select(array('userSurveyID', 'MIN(timestamp) timestamp'))
->from('user_survey_status_entries')
// Instead of setting the parameter in the main query below, it could be quoted here:
// ->where('status = ' . $connection->quote(UserSurveyStatus::ACCESSED))
->where('status = :status')
->groupBy('userSurveyID');
$select = $connection->createQueryBuilder()
->select($selectColNames)
->from('user_surveys', 'us')
// Get raw subquery SQL and wrap in brackets.
->leftJoin('us', sprintf('(%s)', $subSelect->getSQL()), 'firstAccess', 'us.userSurveyID = firstAccess.userSurveyID')
// Parameter used in subquery must be set in main query.
->setParameter('status', UserSurveyStatus::ACCESSED)
->where('us.surveyID = :surveyID')->setParameter('surveyID', $surveyID);