powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Порядок вычисления переменных
19 сообщений из 19, страница 1 из 1
Порядок вычисления переменных
    #38968990
mysql_noon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день. Читаю в доке следующий абзац
For other statements, such as SELECT, you might get the results you expect, but this is not guaranteed. In the following statement, you might think that MySQL will evaluate @a first and then do an assignment second:

Код: sql
1.
SELECT @a, @a:=@a+1, ...


However, the order of evaluation for expressions involving user variables is undefined.
Я понял так, что никто мне не гарантирует, что сперва покажется значение переменной @a, а затем этой к переменной прибавится ещё единица. Может быть наоборот, сперва прибавление единицы, а потом отображение значения переменной.

Написал тестовый запросик
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
SET @prev = '';
SET @grp  = null ;

SELECT t.*
  from (
    select t.*
          ,CASE WHEN IFNULL(@grp, '#') != t.gr
                THEN @prev := null
           END                                as q
          ,@grp := t.gr
          ,CASE when @prev = ''
                then ''
                else STR_TO_DATE(@prev, '%d.%m.%Y')
            end                                             as prev
          ,@prev :=  DATE_FORMAT(t.dd, '%d.%m.%Y')          as dd2
      from (  SELECT t.*
                FROM (  SELECT STR_TO_DATE('01.05.2015', '%d.%m.%Y') as dd,  1 as gr
                        UNION all
                        SELECT STR_TO_DATE('01.06.2015', '%d.%m.%Y') as dd,  1 as gr
                        UNION all
                        SELECT STR_TO_DATE('01.07.2015', '%d.%m.%Y') as dd,  1 as gr
                        UNION all
                        SELECT STR_TO_DATE('02.08.2015', '%d.%m.%Y') as dd,  2 as gr
                        UNION all
                        SELECT STR_TO_DATE('01.09.2015', '%d.%m.%Y') as dd,  1 as gr
                        UNION all
                        SELECT STR_TO_DATE('02.10.2015', '%d.%m.%Y') as dd,  2 as gr
                        UNION all
                        SELECT STR_TO_DATE('01.11.2015', '%d.%m.%Y') as dd,  1 as gr
                    ) t
               ORDER by t.gr
                       ,t.dd
           ) t
       ) t
 ORDER by t.dd
         ,t.gr


Как тогда быть, если нужно сперва отобразить, потом изменить именно в определенном порядке (имитировать аналитические функции) и как быть уверенным, что оптимизатор не перепишет запрос и не начнёт выполнять запрос по другому, не в нужном мне порядке?

Версия 5.5.
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969006
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mysql_noonКак тогда быть, если нужно сперва отобразить, потом изменить именно в определенном порядке (имитировать аналитические функции) и как быть уверенным, что оптимизатор не перепишет запрос и не начнёт выполнять запрос по другому, не в нужном мне порядке?
А никак. Поля выходного набора РАВНОЗНАЧНЫ. И управлять порядком их вычисления в принципе невозможно.

Может, сразу озвучите конкретную задачу? и лучше - в новой теме...
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969015
lamer yuga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
GROUP BY выполняет группировку совмещенную с сортировкой
Если нужно нумеровать в другом порядке - сделайте это во внешнем запросе.
Должно получиться...
Код: sql
1.
2.
3.
4.
5.
6.
select @npp:=@npp+1 npp, g.* 
from (
  select ...
  group by ...
  )g
order by ...
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969021
mysql_noob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
задача банальна - взять предыдущее значения в разрезе группы, т.е. нужно с имитировать функцию Lag (t.dd) over (partition by t.gr order by t.dd) в других СУБД.
Подзапросом нереально, таблица тяжелая, 150 мил. записей, индексов нет - не дождаться ответа. Может скоро разобьём на партиции и добавим индекс, но сейчас надо так. Время за один проход сканирования таблицы, в принципе, приемлемое, но вложенные циклы с полным сканированием всё убивают.

Если нужно, то могу создать новую тему либо перейти, например, сюда
http://www.sql.ru/forum/1055940/vyborka-na-n-zapisey-vpered-i-nazad?hl=lag
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969025
mysql_noob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
задача банальна - взять предыдущее значения в разрезе группы, т.е. нужно с имитировать функцию Lag (t.dd) over (partition by t.gr order by t.dd) в других СУБД.
Подзапросом нереально, таблица тяжелая, 150 мил. записей, индексов нет - не дождаться ответа. Может скоро разобьём на партиции и добавим индекс, но сейчас надо так. Время за один проход сканирования таблицы, в принципе, приемлемое, но вложенные циклы с полным сканированием всё убивают.
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969030
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mysql_noobмогу создать новую темуЖивите здесь, я вроде все успел сюда перетащить :)
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969031
mysql_noob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
lamer yugaGROUP BY выполняет группировку совмещенную с сортировкой
Если нужно нумеровать в другом порядке - сделайте это во внешнем запросе.
Должно получиться...
Код: sql
1.
2.
3.
4.
5.
6.
select @npp:=@npp+1 npp, g.* 
from (
  select ...
  group by ...
  )g
order by ...


А есть гарантии, что оптимизатор не перепишет запрос и не изменит порядок вычислений?

miksoft,
Спасибо!
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969041
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mysql_noon,

делать разными операторами Sql.
сначала первое действие, потом второе и т.д.
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969042
mysql_noob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
lamer yugaGROUP BY выполняет группировку совмещенную с сортировкой
Если нужно нумеровать в другом порядке - сделайте это во внешнем запросе.
Должно получиться...
Код: sql
1.
2.
3.
4.
5.
6.
select @npp:=@npp+1 npp, g.* 
from (
  select ...
  group by ...
  )g
order by ...


Если честно, я так и не понял, как мне поможет group by, если мне на одном уровне select нужно одновременно читать и записывать значение переменной.
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969046
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А, кстати, этот момент есть в нашем FAQ-е - 8379530
Не уверен, что там все правильно, но идея ясна - воспользоваться вызовом нейтральной функции. Тогда аргументы функции всегда буду вычисляться до присвоения.
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969050
lamer yuga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akinamysql_noonКак тогда быть, если нужно сперва отобразить, потом изменить именно в определенном порядке (имитировать аналитические функции) и как быть уверенным, что оптимизатор не перепишет запрос и не начнёт выполнять запрос по другому, не в нужном мне порядке?
А никак. Поля выходного набора РАВНОЗНАЧНЫ. И управлять порядком их вычисления в принципе невозможно.
Вроде бы в доке я читал, что порядок вычислений значений переменных (в рамках одной записи) строго последовательный...
Да и иначе бы резко падала эффективность использования переменных в запросах

межстрочные вычисления переменных зависят от порядка поступления строк (т.е. от ORDER BY)

Во всяком случае, как правило так и происходит
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969053
lamer yuga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mysql_nooblamer yugaGROUP BY выполняет группировку совмещенную с сортировкой
Если нужно нумеровать в другом порядке - сделайте это во внешнем запросе.
Должно получиться...
Код: sql
1.
2.
3.
4.
5.
6.
select @npp:=@npp+1 npp, g.* 
from (
  select ...
  group by ...
  )g
order by ...


Если честно, я так и не понял, как мне поможет group by, если мне на одном уровне select нужно одновременно читать и записывать значение переменной.Это был ответ на пост от 2013 года :) Занесло как новый - ну я на него и ответил, не посмотрев на дату
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969066
lamer yuga
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
mysql_noonДобрый день. Читаю в доке следующий абзац
For other statements, such as SELECT, you might get the results you expect, but this is not guaranteed. In the following statement, you might think that MySQL will evaluate @a first and then do an assignment second:

Код: sql
1.
SELECT @a, @a:=@a+1, ...


However, the order of evaluation for expressions involving user variables is undefined.
Я понял так, что никто мне не гарантирует, что сперва покажется значение переменной @a, а затем этой к переменной прибавится ещё единица. Может быть наоборот, сперва прибавление единицы, а потом отображение значения переменной.

Написал тестовый запросик
http://sqlfiddle.com/#!2/9eecb7/162 v.5.5
Код: sql
1.
2.
select @a, @a:=@a+10, @a:=@a-100, @a:=@a+40, @a
from(select @a:=100)v;

результат - как и ожидалось, все по порядку@a @a:=@a+10 @a:=@a-100 @a:=@a+40 @a100 110 10 50 50
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969075
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Мне пока не приходилось сталкиваться со случаем, когда бы вычисления в выходном наборе выполнялись НЕ в том порядке, в каком они перечислены в тексте запроса. И, в общем, я не вижу оснований к тому, что этот порядок бы не соблюдался - просто потому, что не существует алгоритмов оптимизации порядка вычисления выражений выходного набора (да и за каким хреном бы его делать? овчинка выделки не стОит).

К слову, у меня LAG() получился попроще твоего, кажется...
http://sqlfiddle.com/#!9/58240/7
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969087
mysql_noob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
lamer yuga,
авторAs a general rule, other than in SET statements, you should never assign a value to a user variable and read the value within the same statement . For example, to increment a variable, this is okay:

Код: sql
1.
SET @a = @a + 1;


For other statements, such as SELECT, you might get the results you expect, but this is not guaranteed . In the following statement, you might think that MySQL will evaluate @a first and then do an assignment second:

SELECT @a, @a:=@a+1, ...;
However, the order of evaluation for expressions involving user variables is undefined.
http://dev.mysql.com/doc/refman/5.5/en/user-variables.html

lamer yugamysql_noonДобрый день. Читаю в доке следующий абзац
пропущено...

Я понял так, что никто мне не гарантирует, что сперва покажется значение переменной @a, а затем этой к переменной прибавится ещё единица. Может быть наоборот, сперва прибавление единицы, а потом отображение значения переменной.

Написал тестовый запросик
http://sqlfiddle.com/#!2/9eecb7/162 v.5.5
Код: sql
1.
2.
select @a, @a:=@a+10, @a:=@a-100, @a:=@a+40, @a
from(select @a:=100)v;

результат - как и ожидалось, все по порядку@a @a:=@a+10 @a:=@a-100 @a:=@a+40 @a100 110 10 50 50
Из доки как раз и следует, что может развращаться правильный результат, но он не детерменирован. Не хотелось бы, чтобы в определенных ситуациях отчет выдавал неверные вычисления, которые основаны на неверном результате этих переменных.

MasterZivmysql_noon,
делать разными операторами Sql.
сначала первое действие, потом второе и т.д.
Внимательно посмотрел и понял, что не получится. Зависимость одной переменной от другой внутри одного оператора select. Если бы не было разреза групп, то может быть и получилось. А так нужно отслеживать переход групп.
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38969117
mysql_noob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AkinaК слову, у меня LAG() получился попроще твоего, кажется...
http://sqlfiddle.com/#!9/58240/7
Нуда, я перемудрил как-то )
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38970295
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftА, кстати, этот момент есть в нашем FAQ-е - 8379530
Не уверен, что там все правильно, но идея ясна - воспользоваться вызовом нейтральной функции. Тогда аргументы функции всегда буду вычисляться до присвоения.

...угу, внутри нескольких функций порядок детерминирован.

7489069 ...в самом конце

Примечания:
@rownum:=1+least(0,@typex:=ta.type) гарантирует обновление @typex
после проверки "if(@typex=ta.type..."
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38970296
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mysql_noobAkina,
задача банальна - взять предыдущее значения в разрезе группы, т.е. нужно с имитировать функцию Lag (t.dd) over (partition by t.gr order by t.dd) в других СУБД.
Подзапросом нереально, таблица тяжелая, 150 мил. записей, индексов нет - не дождаться ответа. Может скоро разобьём на партиции и добавим индекс, но сейчас надо так. Время за один проход сканирования таблицы, в принципе, приемлемое, но вложенные циклы с полным сканированием всё убивают.


...если таких запросов много и надо быстро то
подходите к задаче более основательно:

1. Например добаить ЛАГ и ЛЕАД значении в каждую запись
одним проходом а потом быстро вычислять то что нужно.

3. вообше делите сложные запросы на части и выполняйте в независимых простых СКЛ-ах
Любые джоинты на больших таблицах вывалятся из памяти на диск
и все зависинет на минуты/часы и натрете мозоль диску.

2. посмотрите на процедурный курсор.
Возможно это поможет не вывалится на диск и закончится быстрее.
Кроме того в процедуре можно "партицировать"
курсор по блоку груп.

4. Добавить много-много памяти

5. Купить Оракле.

6. Почитайте про ОЛАП
...
Рейтинг: 0 / 0
Порядок вычисления переменных
    #38970488
mysql_noob
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbc, благодарю за советы. Попробую процедурное расширение в mysql.

Покупка oracle, конечно, кардинально бы всё решило, но увы.
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Порядок вычисления переменных
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]