Приведите int к строке в предложении where

Если вы хотите использовать параметры для 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);
});
0
задан Joel Coehoorn 16 January 2019 в 15:45
поделиться

2 ответа

Почему бы просто не использовать 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.

0
ответ дан Yogesh Sharma 16 January 2019 в 15:45
поделиться

Похоже, у нас есть значение 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

Но это в основном улучшения производительности. Они также могут решить вашу проблему, но только как побочный эффект, и я не могу знать наверняка, потому что у нас нет четкого описания того, что пошло не так.

Что подводит меня к последнему пункту. Нам нужно лучше понять, что означает «не работает». «Не работает» без дополнительного объяснения ошибки или некорректного поведения никогда не достаточно хорошо.

0
ответ дан Joel Coehoorn 16 January 2019 в 15:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: