1

我想用 yii2 框架添加过滤条件,这个条件必须生成以下请求:

select count(*) from v_ressource
where 
(
    (
        str_to_date('27/04/2016', '%d/%m/%Y')
        between str_to_date(erDateDebut, '%d/%m/%Y')
        and str_to_date(erDateFin, '%d/%m/%Y')
    )
    and erDateFin is not null
)
or
(
    (
        str_to_date('27/04/2016', '%d/%m/%Y') 
        between str_to_date(erDateDebut, '%d/%m/%Y') 
        and now()
    )
    and erDateFin is null
);

如您所见,“或”条件中有“和”条件。

我的 ModelSearch 中有以下代码:

    $query
        ->andFilterWhere([
            'between',
            'str_to_date(\'' . $this->dateRecherche . '\', \'%d/%m/%Y %H:%i\')',
            new Expression('str_to_date(erDateDebut, \'%d/%m/%Y %H:%i\')'),
            new Expression('str_to_date(erDateFin, \'%d/%m/%Y %H:%i\')'),
        ])
        ->andFilterWhere([
            'not', ['erDateFin' => null],
        ]);

    $query
        ->orFilterWhere([
            'between',
            'str_to_date(\'' . $this->dateRecherche . '\', \'%d/%m/%Y %H:%i\')',
            new Expression('str_to_date(erDateDebut, \'%d/%m/%Y %H:%i\')'),
            new Expression('now()'),
        ])
        ->andFilterWhere([
            'is', 'erDateFin', null,
        ]);

两者都是 null 和 is not null 条件不会出现在生成的请求中并且没有“嵌套”条件(以及 or 条件中的条件)

谢谢你的帮助

4

1 回答 1

1

andFilterWhere并且orFilterWhere不允许以这种方式嵌套,因为它们对查询对象进行操作 - 而不是对条件对象进行操作。您可以这样定义您的查询:

$query->where(
    ['and',
        [
            'between',
            'str_to_date(\'' . $this->dateRecherche . '\', \'%d/%m/%Y %H:%i\')',
            new Expression('str_to_date(erDateDebut, \'%d/%m/%Y %H:%i\')'),
            new Expression('str_to_date(erDateFin, \'%d/%m/%Y %H:%i\')'),
        ],
        [
            'not', ['erDateFin' => null],
        ]
    ]);

$query->orWhere(
    ['and',
        [
            'between',
            'str_to_date(\'' . $this->dateRecherche . '\', \'%d/%m/%Y %H:%i\')',
            new Expression('str_to_date(erDateDebut, \'%d/%m/%Y %H:%i\')'),
            new Expression('now()'),
        ],
        [
            'is', 'erDateFin', null,
        ]
    ]);

您甚至可以将它们全部放入一个where方法调用中:

$query->where(
    ['or',
        ['and',
            [
                'between',
                'str_to_date(\'' . $this->dateRecherche . '\', \'%d/%m/%Y %H:%i\')',
                new Expression('str_to_date(erDateDebut, \'%d/%m/%Y %H:%i\')'),
                new Expression('str_to_date(erDateFin, \'%d/%m/%Y %H:%i\')'),
            ],
            [
                'not', ['erDateFin' => null],
            ]
        ],
        ['and',
            [
                'between',
                'str_to_date(\'' . $this->dateRecherche . '\', \'%d/%m/%Y %H:%i\')',
                new Expression('str_to_date(erDateDebut, \'%d/%m/%Y %H:%i\')'),
                new Expression('now()'),
            ],
            [
                'is', 'erDateFin', null,
            ]
        ]
    ]);

我使用了where方法,而不是filterWhere方法,因为您可能不想从查询中删除空操作数。更多关于过滤的信息可以在这里找到。其中还记录了andor运算符。

您可能已经知道,计数可以用

$count = $query->count();
于 2016-04-28T09:14:23.730 回答