Zend2 Db \选择动态IN子句与HAVING

时间:2017-08-31 14:14:33

标签: php mysql zend-framework2 zend-db

SELECT 
    CONCAT_WS(' ', user.firstname, user.lastname) AS name,
    user.email AS email
FROM
    user
WHERE
    op_id IN (
        SELECT 
            user.op_id AS op_id
        FROM
            user
        WHERE
            last_login_on IS NOT NULL
        GROUP BY op_id
        HAVING (SUM(IF(DATE(last_login_on) > DATE(DATE_SUB(NOW(), INTERVAL 31 DAY)), 1, 0)) = 0)
        ORDER BY op_id ASC)
AND role_type = 'owner';

从上面的SQL中,如果在上个月内登录,则所有用户分配1,如果未登录超过一个月,则分配0,然后将结果集减少为具有0登录的那些作为IN子句,然后选择op_id所有者详细信息。

这已在Zend DB \ Select中复制,并且所有工作都按预期工作,除了HAVING子句在生成的SQL查询中丢失时用作新表达式(“SUM(IF(DATE(last_login_on)> DATE( DATE_SUB(NOW(),INTERVAL 31 D)),1,0))= 0“)。

这个表达式可以应用于$ select-> having()语句吗?

1 个答案:

答案 0 :(得分:0)

这应该是可能的, {(1}}的()方法接受表达式作为参数。问题是您使用的表达式:Select\Zend\Db\Sql\Expression,尽管\Zend\Db\Sql\Predicate\Expression继承自Predicate\Expression。老实说,差异对我来说并不完全清楚,但我能够在不丢失的情况下创建您的查询:

Sql\Expression

这应该回显这样的字符串:

$select = new Select('user');

$inSelect = new Select('user');
$inSelect->columns(array('op_id' => 'op_id'));
$inSelect->where(new \Zend\Db\Sql\Predicate\IsNotNull('last_login_on'));
$inSelect->group('op_id');
$inSelect->order(array('op_id' => 'asc'));
$inSelect->having(new \Zend\Db\Sql\Predicate\Expression('SUM(IF(DATE(last_login_on) > DATE(DATE_SUB(NOW(), INTERVAL 31 DAY)), 1, 0)) = 0'));

$inExpression = new In('op_id', $inSelect);
$select->where($inExpression);
$select->where(array('role_type' => 'owner'), PredicateSet::OP_AND);

echo $select->getSqlString();

修改

ZF2版本:2.4.9