Если вы хотите использовать параметры для a, b, c, d в Laravel 4
Model::where(function ($query) use ($a,$b) {
$query->where('a', '=', $a)
->orWhere('b', '=', $b);
})
->where(function ($query) use ($c,$d) {
$query->where('c', '=', $c)
->orWhere('d', '=', $d);
});
Почему бы просто не использовать cast()
? :
select cast(t.TimeEntityElementId as date)
from dbo.Time t
where cast(t.TimeEntityElementId as date) < '2019-01-01';
N
не подходит для этого, потому что TimeEntityElementId
имеет тип datetime
& amp; N
означает «набор символов национального языка», что означает, что вы передаете данные типа NCHAR
, NVARCHAR
или NTEXT
.
Похоже, у нас есть значение int
, где вам действительно нужно DateTime
. Исправление этого в определении таблицы действительно спасет вас от МНОГО неприятностей. Но в этом случае мы все еще можем улучшить некоторые вещи с помощью существующих данных.
Начните с этого условия WHERE:
convert(date,CONVERT(varchar(10),t.TimeEntityElementId,101)) < N'2019-01-01'
Использование здесь функций CONVERT()
не позволяет использовать любой индекс, который вы можете иметь для TimeEntityElementId
. Вместо этого мы можем воспользоваться значениями с сегментами, организованными с хорошим порядковым размером и положением. Это похоже на то, как Sql Server на самом деле хранит даты / даты, но он вырезает блок из 10 000 номеров из целочисленного пространства в год, а не просто 365, как это делает Sql Server. Это означает, что вы можете значительно сократить код и написать то же условие, что и при простом числовом сравнении, например:
t.TimeEntityElementId < 20190101
Для этого не нужно выполнять какие-либо преобразования для каждой строки и все еще можно использовать TimeEntityElementId
index, и поэтому должен выполнять НАМНОГО быстрее, потенциально многократных порядков.
Конечно, вам все еще нужно беспокоиться о стороне SELECT, но теперь вы конвертируете только строки, которые проходят предложение WHERE, а не каждую строку в таблице, и этого может быть достаточно для решения проблемы. , Но мы можем сделать больше. Мы также можем удалить преобразование SELECT с помощью функции DATEFROMPARTS()
:
DATEFROMPARTS(t.TimeEntityElementId/10000, (t.TimeEntityElementId % 10000) / 100, t.TimeEntityElementId % 100)
Это позволяет избежать необходимости разбора строки на дату и время, что на самом деле является довольно медленной операцией. Как ни странно вышеприведенное выражение, это все математика, которую процессор может делать очень эффективно. Разбор строки должен учитывать все виды культурных / интернациональных причуд и, следовательно, имеет тенденцию быть намного медленнее. Это также менее чувствительно к случаю, когда TimeEntityElementId
имеет строки, которые не соответствуют формату даты. Вы все еще можете получить странные результаты, но по крайней мере это не должно просто провалить весь запрос.
Соберите все это вместе так:
SELECT
DATEFROMPARTS(t.TimeEntityElementId/10000, (t.TimeEntityElementId % 10000) / 100, t.TimeEntityElementId % 100)
FROM dbo.Time t
WHERE t.TimeEntityElementId < 20190101
Но это в основном улучшения производительности. Они также могут решить вашу проблему, но только как побочный эффект, и я не могу знать наверняка, потому что у нас нет четкого описания того, что пошло не так.
Что подводит меня к последнему пункту. Нам нужно лучше понять, что означает «не работает». «Не работает» без дополнительного объяснения ошибки или некорректного поведения никогда не достаточно хорошо.