powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / MySQL [игнор отключен] [закрыт для гостей] / переменные, помогите разобраться
19 сообщений из 19, страница 1 из 1
переменные, помогите разобраться
    #38710121
usermuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В селекте использую переменные,

авторSELECT ....
@var1 := table.fieldA + table.fieldB AS result1
@var2 := table.fieldC + @var1 AS result2
FROM ...


В результате наблюдаю такие вещи.
а) при первом выполнении колонка result2 = NULL для всех полей;
б) result2 одинаковый для всех записей в выдаче; если при вычислении использовать имена полей, а не переменную var1, то значения правильные.

Подскажите, товарищи спецы, почему так получается.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710131
Users
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
usermuser,

а проинитить переменную значением, не? :) set @var1 = 0

А иначе она null и все, что к null прибавляется - им же и становится.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710144
usermuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
если, инициализацию ставлю перед селектом то в результате во всей колонке одни нули.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710146
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
usermuser,

Покажите воспроизводимый код.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710159
usermuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
авторSET @total = 0;
SET @totalA := 0;
SET @totalB := 0;

SELECT r.id
, @total := SUM(CEIL((CASE WHEN s.seasonTo < 1414785600 THEN s.seasonTo ELSE 1414785600 END
- CASE WHEN s.seasonFrom > 1414699200 THEN s.seasonFrom ELSE 1414699200 END )/86400)) AS total

, @totalA := @total*rate.rateA AS totalA
, @totalB := @total*rate.rateB AS totalB
, @totalA + @totalB AS totalC

FROM services r
LEFT JOIN seasons s ON CASE WHEN s.seasonFrom > 1414699200 THEN s.seasonFrom ELSE 1414699200 END
< CASE WHEN s.seasonTo < 1414785600 THEN s.seasonTo ELSE 1414785600 END
LEFT JOIN rates rate ON (rate.roomID = r.roomID AND rate.seasonID = s.seasonID)
GROUP BY id
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710184
usermuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
при инициализации переменных, totalC всё время равно 0. Такое ощущение, что переменная обнуляется в самом запросе, но это же не так ведь? Чем вызвано такое поведение?
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710219
miksoft
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
usermuser,

а как именно вы этот код запускаете?
в консоли mysql пробовали?
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710267
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
miksoftusermuser,

а как именно вы этот код запускаете?
в консоли mysql пробовали?

usermuser,

да, это тут важно.

переменная задается на сессию конекта.
Во многих фреимворках используется
конекш-пул. Т.е очень возможна
ситуация когда SET @a.... прошло на одном конекте
а следуюшая строка послана через другой конект
и переменная "потерялась"

Что бы этого избежать надо или делать все одной падачей
(если драйвер понимает несколько команд кучей)
или задавайте переменную на лету:

Код: sql
1.
2.
3.
select @a a1
from dual,
(select @a := 33) z
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710322
usermuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbcmiksoftusermuser,

а как именно вы этот код запускаете?
в консоли mysql пробовали?

да, это тут важно.

или задавайте переменную на лету:



спасибо за помощь.
код запускаю в клиенте HeidiSQL.

А как правильно сформировать запрос в моём случае с инициализацией переменных на лету? С подобным синтаксисом не сталкивался, пример не уяснил. Буду признателен, если подскажите.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710324
usermuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ещё я тут вычитал, что работать с переменными вообще опасно, может вернуться непредсказуемый результат. Насколько оправданы подобные опасения?
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710339
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
usermuserjavajdbcпропущено...


да, это тут важно.

или задавайте переменную на лету:



спасибо за помощь.
код запускаю в клиенте HeidiSQL.

А как правильно сформировать запрос в моём случае с инициализацией переменных на лету? С подобным синтаксисом не сталкивался, пример не уяснил. Буду признателен, если подскажите.



Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
SELECT r.id
, @total := SUM(CEIL((CASE WHEN s.seasonTo < 1414785600 THEN s.seasonTo ELSE 1414785600 END
- CASE WHEN s.seasonFrom > 1414699200 THEN s.seasonFrom ELSE 1414699200 END )/86400)) AS total

, @totalA := @total*rate.rateA AS totalA
, @totalB := @total*rate.rateB AS totalB
, @totalA + @totalB AS totalC

FROM 
(select @total:=0, @totalA:=0,@totalB:=0) z JOIN
services r
LEFT JOIN seasons s ON CASE WHEN s.seasonFrom > 1414699200 THEN s.seasonFrom ELSE 1414699200 END
< CASE WHEN s.seasonTo < 1414785600 THEN s.seasonTo ELSE 1414785600 END
LEFT JOIN rates rate ON (rate.roomID = r.roomID AND rate.seasonID = s.seasonID)
GROUP BY id



(для читабельности, не называйте одинаково алиасы и переменные: @totalA <-> totalA)
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710341
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
usermuserЕщё я тут вычитал, что работать с переменными вообще опасно, может вернуться непредсказуемый результат. Насколько оправданы подобные опасения?


да, частенько бывают непонятки.
например, вот прямо в вашем
примере, я не берусь судить что будет
так как вы хотите -- у вас ГРОУП БУ .

Надежнее сделать селект с групбаем
без переменных как подзапрос
и его окружить еше одним селектом где и вычисляйте
производные суммы -- если сможете -- все БЕЗ переменных.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710378
usermuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbcFROM
(select @total:=0, @totalA:=0,@totalB:=0) z JOIN
services r


В таком варианте все колонки по нулям. Как будто в цикле обнуляются переменные и ничего не сохраняется.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710379
usermuser
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
javajdbcНадежнее сделать селект с групбаем
без переменных как подзапрос
и его окружить еше одним селектом где и вычисляйте
производные суммы -- если сможете -- все БЕЗ переменных.

Это пока сложно для моего понимания. На данный момент нормально работающий вариант без переменных, это тупо заменить сами переменные аналогичным кодом. Коряво, да, зато работает.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710384
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
usermuserjavajdbcFROM
(select @total:=0, @totalA:=0,@totalB:=0) z JOIN
services r


В таком варианте все колонки по нулям. Как будто в цикле обнуляются переменные и ничего не сохраняется.

Скорее всего GROUP BY сбивает расчеты в SELECT блоке.
Если получается по логике, сделайте селект-подселект без переменных:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
select
  id, 
  total,
  total * 33 total1,
  total * 66 total2 
from
(
select 
   id,
   sum(a) total
from t1
where id<3333
) z
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38710385
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
GROUP BY забыл

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
select
  id, 
  total,
  total * 33 total1,
  total * 66 total2 
from
(
select 
   id,
   sum(a) total
from t1
where id<3333
group by id
) z
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38712265
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
дык сдесь сразу понятно было...сначала пройдёт обработка переменных в полях, которые не связаны с агрегацией, а потом поля с агрегацией.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38712634
Фотография javajdbc
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alex564657498765453дык сдесь сразу понятно было...сначала пройдёт обработка переменных в полях, которые не связаны с агрегацией, а потом поля с агрегацией.

Вах маладец! Спасибо, да, дарагой, приходи чаще,
рады будем, приходи и сразу говори как надо.
Реально поможеш -- братаны не будут головы ломать.
Пиво будем кушать, кальмаров кушать,
красивых девочек танцеват.
...
Рейтинг: 0 / 0
переменные, помогите разобраться
    #38712890
alex564657498765453
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
javajdbcalex564657498765453дык сдесь сразу понятно было...сначала пройдёт обработка переменных в полях, которые не связаны с агрегацией, а потом поля с агрегацией.

Вах маладец! Спасибо, да, дарагой, приходи чаще,
рады будем, приходи и сразу говори как надо.
Реально поможеш -- братаны не будут головы ломать.
Пиво будем кушать, кальмаров кушать,
красивых девочек танцеват.

всегда пожалуста...могу больше сказать.

для начала, я уже понял что я не понятно выразился...реплика была для варианта с переменными твоего

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

в итоге получиться, что для вычисления не агрегированых значений, будет использоваться не сумма для текущей группы, а сумма вычисленная для предыдущей.

пример(первый)
Код: sql
1.
2.
3.
4.
5.
6.
7.
select id,@t:=sum(field),@tt:=@t+1 as 'tt'
from table
group by id;

select id,@t:=sum(field),@tt:=@t+1 as 'tt'
from table
group by id,`tt`;



первый запрос выдаст результат на подобе этого
1 10 1
1 20 11
1 123 21
1 4 124
1 0 5
тоесть вычисление третьего значения, проиходит использую сумму предыдущей группы

а вот другой вопрос, будет выполняться по другому.
ведь мы явно указали третий столбик для групировки, тоесть не вычислив его, мы впринципе
не может начать групировать записи.
тут получиться на подобе того что автор сначала делал. для вычисления его, будет использована последняя сумма предыдущего запроса - получиться константа для всех записей второго запроса.

ЗЫ
Если рассуждать более строго (мускл и насколько я понимаю отсальные субд тоже)
то запись
select id,@t:=id+1,@tt:=@t+1

не следует ожидать что для айди = 1 мы получим 1 2 3

это как со значением переменой цикла фор после самого цикла, она всегда равна макс значение щётчика плюс один, но везде говорят, что не надо на это ращитывать, ибо хз как завтра может измениться компилятор/интерпритатор... данный момент не стандартизирован - пока что так.

так вот порядок обработки столбцов тоже не специфицирован, более того - реляционная модель как раз таки подразумевает, что от порядка столбцов ничего не зависит.

ращитывать что пулучим 1 2 3 , тоже что ращитывать при
select * from table получим записи отсортированые по примари кею автоинкрементному.

таки да, получим - в большинстве случаев, но в меньшинстве изза работы оптимизатора это
не так.

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


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