Показать полную графическую версию : украшаем запрос MS SQL
Не совсем то. 2 вызова одно функции приведёт к вычислению 2 раз одного и того же запроса, а мне хочется на этом съэкономить и не засорять базу
pva, это уже - маленький простой запрос - его можно слегка переформулировать, разбить на части, усложнить. Но MS SQL это не тупой интерпретатор наподобие MySQL - простой запрос он сам выполнит оптимальным образом основываясь на текущей ситуации. Промежуточные таблицы, подпрограммы и т.п. только ухудшат его работу и читаемость.
Занялся народным творчеством дабы улучшить жизнь любимым девушкам в любимой конторе. Родил кучу вопросов. Продолжаем:
1. Есть ли стандартная функция в SQL, которая выбираем минимум или максимум из 2-х значений
2. Можно ли как-то сделать временную функцию (для экономии кода) вида:
-- ограничить и превратить во float
CREATE function dbo.fmin(@date_a datetime, @date_b datetime) returns float
as
begin
declare @a float, @b float;
select @a = convert(float, @date_a), @b = convert(float, @date_b);
return case when @a<@b then @a else @b end;
end
на данный момент я сделал в базе функцию
CREATE function dbo.fmin(@a float, @b float) returns float
as return case when @a<@b then @a else @b end;
и в запросе стоит 8 раз convert(float, ...) потому что типа неявные преобразования datetime в float не разрешены
а зачем datetime во float переводить? - это немножко хак, без которого вполне можно обойтись.
select предназначен немножко для другого, просто присвоить переменной значение можно через set:
set @a = convert(float, @date_a), @b = convert(float, @date_b)
временных функций в T-SQL тоже нету - зачем? Если она нужна - она не должна быть временной; если используется только однажды - красивости можно не наводить. На самом деле, чтобы не "замусоривать" БД - у всех объектов есть владелец и область видимости. Т.е. при правильном проектировании обычный пользователь и не увидит функции и процедуры администратора.
Продолжаем тему про временный view. У меня одна процедурка время от времени блокировала работу всегод отдела. Нужно выбрать последнее по дате значение какого-то параметра из сложного запроса, сделано типа так:
select top 1 /*запрос*/
order by d.date desc
Опытным путём выяснил причину: вот если убрать order by, срабатывает моментом и никого не вешает. В результате переделал так (и всё работает замечательно):
select top 1 /*запрос*/
where d.date=(select max(d.date) from /*этот же запрос*/)
1. можно как-то сделать так, чтобы 2 раза не писать один запрос (типа "сделать временный view")
2. есть ли альтернативные способы выбрать из таблицы элемент с максимальным значением, без такой блокировки других пользователей
select top 1 /*запрос*/
order by d.date desc »
Мда.
Задача: Вывести строку в которой d.date максимальна (последнее по дате)
Решение: Вывести ВСЮ таблицу (естественно создается какая-то внутренняя системная буферная переменная), отсортировать (в данном буфере), и взять первое значение.
А если в таблице миллионы строк?
Не индус писал?
Кстати поле d.date - индексированно?
====
2. есть ли альтернативные способы выбрать из таблицы элемент с максимальным значением, без такой блокировки других пользователей »
Для рекомендаций нужно знать как структуру запроса так и таблиц откуда оно берется.
Временной таблицы не было, стоял большой where, который я переделал в join и переименовал однобуквенные переменные в многобуквенные. Дата проиндексирована (по возрастанию)
select top 1
@last_measure_id = order_.measure_id,
@last_rate = order_.rate
from
order_
join doc_ doc2 on (order_.doc_id=doc2.doc_id)
join agent_ on (agent_.agent_id=doc2.d_agent_id and agent_.agent_type in (0,2))
join doc_ doc1 on (doc2.other=doc1.other and doc2.date<=doc1.date and doc2.handled=1)
where
order_.original_id = @p_id
and doc2.date = (
select
max(doc2.date)
from
order_
join doc_ doc2 on (order_.doc_id=doc2.doc_id)
join agent_ on (agent_.agent_id=doc2.d_agent_id and agent_.agent_type in (0,2))
join doc_ doc1 on (doc2.other=doc1.other and doc2.date<=doc1.date and doc2.handled=1)
where
order_.original_id = @p_id);
© OSzone.net 2001-2012
vBulletin v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.