当前位置: 首页 > 面试题库 >

使用子句2 DBAL加入子查询

唐涛
2023-03-14
问题内容

我正在重构Zend Framework 2 应用程序,以使用准则2.5 DBAL代替Zend_DB(ZF1)。我有以下Zend_Db查询:

$subSelect = $db->select()
    ->from('user_survey_status_entries', array('userSurveyID', 'timestamp' => 'MIN(timestamp)'))
    ->where('status = ?', UserSurveyStatus::ACCESSED)
    ->group('userSurveyID');


$select = $db->select()
    // $selectColNames contains columns both from the main query and 
    // the subquery (e.g. firstAccess.timestamp AS dateFirstAccess).
    ->from(array('us' => 'user_surveys'), $selectColNames)
    ->joinLeft(array('firstAccess' => $subSelect), 'us.userSurveyID = firstAccess.userSurveyID', array())
    ->where('us.surveyID = ?', $surveyID);

这将导致以下MySQL查询:

SELECT `us`.`userSurveyID`, 
    // More columns from main query `us`
    `firstAccess`.`timestamp` AS `dateFirstAccess`
FROM `user_surveys` AS `us`
LEFT JOIN (
    SELECT `user_survey_status_entries`.`userSurveyID`, 
            MIN(timestamp) AS `timestamp` 
    FROM `user_survey_status_entries` 
    WHERE (status = 20) 
    GROUP BY `userSurveyID`
) AS `firstAccess` ON us.userSurveyID = firstAccess.userSurveyID 
WHERE (us.surveyID = '10')

我无法弄清楚如何使用教义2.5查询生成器加入子查询。在主查询中,我需要从子查询中选择列。

我在这里已经读到,该学说不支持加入子查询。如果仍然如此,是否可以使用主义DBAL的SQL查询构建器以其他方式编写此查询?原生SQL对我来说可能不是一个好的解决方案,因为此查询将在代码后面动态扩展。


问题答案:

通过将DQL示例改编为DBAL,我找到了解决方案。诀窍是获取子查询的原始SQL,将其包装在方括号中,然后将其联接。子查询中使用的参数必须在主查询中设置:

$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);


 类似资料:
  • 问题内容: 我有两个要加入的表。 我想要类别表中的所有类别以及用户在category_subscriptions表中订阅的所有类别。 基本上这是我到目前为止的查询: 这很好用,但是我想在查询的末尾添加一个where子句,然后从本质上使它成为一个内部/等参连接。 如何仅使用一个查询获取所有类别以及特定用户订阅的所有类别? category_id是类别表和user_category_subscript

  • 问题内容: 我试图在Postgres 9.1.3中使用此查询: 我收到此错误: 我真的很困惑 根据Postgres文档,WITH子句显示正确。如果我在WITH子句中单独运行查询,则会得到正确的结果。 问题答案: 从精美的手册中: 有两种方法可以使用数据库中其他表中包含的信息来修改表:使用子选择,或在子句中指定其他表。 因此,您只需要一个FROM子句: 错误消息甚至说了很多: 错误:缺少表“ sto

  • 问题内容: 这对我来说是一个常见的SQL查询: 有什么办法可以避免拥有两个几乎相同的子查询?该查询是一个明显的简化,但是性能会受到影响,并且查询的内容不必要地凌乱。 问题答案: 不幸的是,Informix不支持UPDATE语句中的FROM子句。解决方法,您将获得更好的结果(性能),方法是将UPDATE更改为MERGE语句。 仅当您的数据库为11.50或更高版本时,此方法才有效 查看IBM Info

  • 问题内容: 我有以下只需1秒即可执行的sql查询: 但是我需要一个结果集来获取比率大于0的结果。因此,当我将查询更改为此时,需要7分钟的时间来执行: 为什么这会使查询时间从1秒增加到7分钟?由于b表很大,因此我什至尝试使用CTE,但这也没有提高性能。我认为使用CTE可以从中筛选出较小的一组值,因此应该更快一些,但这无济于事: 我不能包括执行计划,因为除了查询之外,我没有对数据库的权限。 问题答案:

  • 嗨,我正在学习java脚本。我目前正在尝试找出正则表达式。当我在文本区域字段中输入某些内容时,我想尝试该选项,自动单击按钮以删除在字段中输入的文本并打印一些默认的正则表达式文本,并用它们的视觉显示替换超文本标记语言实体: