Mysql насколько это грубый хак?

WMix

герр M:)ller
Партнер клуба
ковыряя программу натолкнулся на подобную запись (выдергивание alias поля с помощью (select alias))
Код:
mysql> SELECT 10 AS my_num, (SELECT my_num) * 5 AS another_number, version();
+--------+----------------+---------------------+
| my_num | another_number | version()           |
+--------+----------------+---------------------+
|     10 |             50 | 5.5.46-0+deb8u1-log |
+--------+----------------+---------------------+
1 row in set (0.00 sec)
чет в мануале не нашел описания.
это предсказуемое поведение?
 

WMix

герр M:)ller
Партнер клуба
проблема вот в чем, вчера пробывал повторить этот выкрунтас на маке
Код:
mysql> SELECT 10 AS my_num, (SELECT my_num) * 5 AS another_number, version();
ERROR 1054 (42S22): Unknown column 'my_num' in 'field list'
mysql> show variables like "%version%";
+-------------------------+------------------------------+
| Variable_name           | Value                        |
+-------------------------+------------------------------+
| innodb_version          | 5.7.9                        |
| protocol_version        | 10                           |
| slave_type_conversions  |                              |
| version                 | 5.7.9                        |
| version_comment         | MySQL Community Server (GPL) |
| version_compile_machine | x86_64                       |
| version_compile_os      | osx10.9                      |
+-------------------------+------------------------------+
7 rows in set (0,01 sec)

mysql>
 
Последнее редактирование:

AnrDaemon

Продвинутый новичок
Ээээ…
Код:
mysql> SELECT 10 AS my_num, (SELECT my_num) * 5 AS another_number, version();
+--------+----------------+---------------------------------+
| my_num | another_number | version()                       |
+--------+----------------+---------------------------------+
|     10 |             50 | 5.6.30-1+deb.sury.org~precise+2 |
+--------+----------------+---------------------------------+
1 row in set (0.00 sec)
 

fixxxer

К.О.
Партнер клуба
На всем, что есть под рукой (MariaDB 5.5/10.0, MySQL 5.6) - работает.

5.7 под рукой проверить нету, может, там сломали что-то?
 

fixxxer

К.О.
Партнер клуба
Postgresql таких выкрутасов, кстати, не позволяет:
Код:
ERROR:  column "my_num" does not exist
Но там, конечно, можно так:
Код:
WITH t AS (SELECT 10 AS my_num) SELECT my_num, my_num * 5 AS another_number FROM t;
А вот так точно будет работать вообще везде:
Код:
SELECT my_num, my_num * 5 AS another_number FROM (SELECT 10 AS my_num) t;
 

Hello

Новичок
@AnrDaemon, это точный ответ
Код:
SELECT 10 AS my_num, (SELECT my_num) * 5 AS another_number, version();
+--------+----------------+-----------+
| my_num | another_number | version() |
+--------+----------------+-----------+
|  10 |  50 | 5.5.51  |
+--------+----------------+-----------+
1 row in set (0.00 sec)
 

antson

Новичок
Партнер клуба
@WMix, в документации A select_expr can be given an alias using AS alias_name. The alias is used as the expression's column name and can be used in GROUP BY, ORDER BY, or HAVING clauses.
И явное предупреждение про недопустимость использования в WHERE.
То, что хак работает почти везде не документированная фишка.

А через SET @my_num=10;select @my_num* 5 AS another_number нельзя сделать ?
 

fixxxer

К.О.
Партнер клуба
@WMix, а чем вариант с select ... from (select ... ) alias не подходит? Это классический ansi sql, работать будет везде, задачу решает.
 

WMix

герр M:)ller
Партнер клуба
там ребята постарались, такой 4х уровневый inheritance tree построили классиков эдак на 20 с одним публичным методом типа get() на каждый конечный класс, который в результате строит огромадный sql с 3 union и join в joinax ну и исполняет его (некий список товаров с актуальной ценой и динамическим номером артикула который выставил региональный представитель -- общая база или своя. кстати про этот номер и идет речь ).

выделить поле в from чтот я не готов. там минимум 2 дня копаться и то глубину мысли не поймешь.
есть другое более простое решение типа
PHP:
$db->query('
select 
  '.$this->getArtNrFied().' as art_nr,
  /* вместо (select art_nr) */
  if( '.$this->getArtNrFied().' IN (x,y,z), 1,0 ) as selected ...
')
 

Вурдалак

Продвинутый новичок
там ребята постарались, такой 4х уровневый inheritance tree построили классиков эдак на 20
Когда люди сталкиваются с проблемой, они могут подумать: «Я решу это проблему наследованием!». Теперь у них 10 проблем.
 

fixxxer

К.О.
Партнер клуба
@WMix,
ну можно вроде того
PHP:
$fuckedQuery = $this->getFuckedQueryFromFuckedInteritanceChain();
$db->query('select t.*, t.my_num * 10 as another_num from (' . $fuckedQuery->getSql() . ') t', $fuckedQuery->getBindings());
разница небольшая
 

fixxxer

К.О.
Партнер клуба
Когда люди сталкиваются с проблемой, они могут подумать: «Я решу это проблему наследованием!». Теперь у них 10 проблем.
А то. Тут вон по всем интернетам разошлись очередные вопли страдальца - поимел проблем с наследованием и херовой архитектурой, решил бросить ООП и уйти в монастырь, ну то есть в ФП. Чот я прям ржу. Software architect, мать его.
 
  • Like
Реакции: WMix

WMix

герр M:)ller
Партнер клуба
мне нужно только метод переписать
PHP:
return 'if( /* (select art_nr) */ '.$this->getArtNrFied().' IN (x,y,z), 1,0 ) as selected';
 
Последнее редактирование:

fixxxer

К.О.
Партнер клуба
А, то есть даже не квери-билдер, а вот прямо ручками кусками строк и все это через иерархию наследования.

Ну я даже не знаю... кажется, начать надо с отрывания рук тем, кто это написал.
 
Сверху