Теперь, чтобы упростить логику, я хочу в основном ИСКЛЮЧИТЬ строки, где оба (date
Либо примените формальную булеву логику !(A and B) = !A or !B
, либо просто заметьте, что «исключить, где оба истинны» эквивалентно «включать, если один из них ложен». Таким образом, мы включаем те строки, в которых либо дата не является прошлой (то есть будущей), либо тип не является someType.
->where('row_type', '!=', 'someType')->orWhere('date', '>', Carbon::now())
Если у вас есть и другие условия, в том числе и то, что orWhere
испортит их, вы должны просто использовать для этого вложенность:
// ...other wheres...
->where(function($query) {
$query->where('date', '>', Carbon::now())->orWhere('row_type', '!=', 'someType');
})
->where( // ...other wheres...
Я попытаюсь пройтись по SQL, чтобы показать, что это работает.
CREATE TABLE my_table(Id integer PRIMARY KEY, row_type text, date date);
/* First row is someType and past - it should be excluded */
INSERT INTO my_table VALUES(1,'someType', '2019-03-01');
INSERT INTO my_table VALUES(2,'someType', '2019-03-31');
INSERT INTO my_table VALUES(3,'otherType', '2019-03-01');
INSERT INTO my_table VALUES(4,'otherType', '2019-03-01');
COMMIT;
Запрос в операторе:
SELECT 'Cases from the OP' as '';
SELECT id, row_type, date
FROM my_table
WHERE
CASE
WHEN row_type = 'someType'
THEN date > '2019-03-22%'
END;
/* returns */
2|someType|2019-03-31
Он даже не делает того, что вы заявляете словами. Это также исключает каждую строку, где row_type не является someType. Это эквивалентно row_type = 'someType' AND date > '2019-03-22'
. Чтобы исключить то, что вы заявили, следует исключить, вы должны сделать это еще более сложным:
SELECT id, row_type, date
FROM my_table
WHERE
CASE
WHEN row_type = 'someType'
THEN date > '2019-03-22'
ELSE 1
END;
/* returns */
2|someType|2019-03-31
3|otherType|2019-03-01
4|otherType|2019-03-01
Но было бы проще и уместнее (случаи уместны, когда на самом деле есть несколько случаев) просто написать это:
SELECT ' ' as '';
SELECT 'The same using OR' as '';
SELECT id, row_type, date
FROM my_table
WHERE
(row_type != 'someType' OR date > '2019-03-22');
/* returns */
2|someType|2019-03-31
3|otherType|2019-03-01
4|otherType|2019-03-01
Я обернул условие в скобки, так как вы сказали, что хотите добавить и другие утверждения. И это то, что where(function($q) {$q->...})
сделает.