Определить и использовать переменную с подзапросом?
Обычно я знаю, что "порядок вычисления выражений, включающих пользовательские переменные, не определен", поэтому мы не можем безопасно определить и использовать переменную в том же select
заявление. Но что, если есть подзапрос? Как пример, у меня есть что-то вроде этого:
select col1,
(select min(date_)from t where i.col1=col1) as first_date,
datediff(date_, (select min(date_)from t where i.col1=col1)
) as days_since_first_date,
count(*) cnt
from t i
where anothercol in ('long','list','of','values')
group by col1,days_since_first_date;
Есть ли способ использовать (select @foo:=min(date_)from t where i.col1=col1)
безопасно вместо повторения подзапроса? Если так, могу ли я сделать это в datediff
функция или первый раз, когда появляется подзапрос (или один)?
Конечно, я мог бы сделать
select col1,
(select min(date_)from t where i.col1=col1) as first_date,
date_,
count(*) cnt
from t i
where anothercol in ('long','list','of','values')
group by col1,date_;
а затем сделать некоторую простую постобработку, чтобы получить datediff
, Или я могу написать два отдельных запроса. Но они не отвечают на мой вопрос: можно ли безопасно определить и использовать одну и ту же переменную в запросе и подзапросе.
1 ответ
Во-первых, ваш запрос не имеет смысла, потому что date_
не имеет функций агрегирования. Вы собираетесь получить произвольное значение.
Тем не менее, вы можете повторить подзапрос, но я не понимаю, почему это будет необходимо. Просто используйте подзапрос:
select t.col1, t.first_date,
datediff(date_, first_date),
count(*)
from (select t.*, (select min(date_) from t where i.col1 = t.col1) as first_date
from t
where anothercol in ('long','list', 'of', 'values')
) t
group by col1, days_since_first_date;
Как я уже говорил, значение третьего столбца проблематично.
Примечание: это приводит к дополнительным накладным расходам для материализации подзапроса. Тем не менее, есть group by
в любом случае, данные читаются и записываются несколько раз.