yii2 как создать и подготовить в другом

Я хочу добавить условие фильтра с рамкой 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 и не NULL, не отображаются в сгенерированном запросе, и нет "вложенных" условий (и условия в или условиях).

Спасибо за вашу помощь

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, потому что вы, вероятно, не хотите удалять пустые операнды из запроса. Более подробную информацию о фильтрации можно найти здесь. где также документы и и или или операторы.

Как вы, наверное, уже знаете, подсчет можно сделать с

$count = $query->count();
Другие вопросы по тегам