#mysql #where-clause #tinyint
#mysql #where-предложение #tinyint
Вопрос:
Вот данные в MySQL (8.0.x), работающие с macOS:
ysql> desc t_room;
-------------- ------------------- ------ ----- --------- -------
| Field | Type | Null | Key | Default | Extra |
-------------- ------------------- ------ ----- --------- -------
| roomNum | varchar(60) | NO | PRI | NULL | |
| roomType | varchar(20) | NO | | NULL | |
| roomDesc | varchar(400) | YES | | NULL | |
| rentPayDay | tinyint unsigned | YES | | NULL | |
| rentFee | smallint unsigned | NO | | NULL | |
| asstMine | varchar(400) | YES | | NULL | |
| asstOwner | varchar(400) | YES | | NULL | |
| owner | varchar(30) | YES | | NULL | |
| signDate | date | YES | | NULL | |
| contract | mediumblob | YES | | NULL | |
| roomFacility | varchar(120) | YES | | NULL | |
-------------- ------------------- ------ ----- --------- -------
11 rows in set (0.00 sec)
mysql> select rentPayDay from t_room;
------------
| rentPayDay |
------------
| 15 |
| 20 |
| 25 |
| 10 |
------------
4 rows in set (0.00 sec)
когда я выполняю запрос с предложением where, как показано ниже, все в порядке:
mysql> select roomNum, owner, rentPayDay from t_room where rentPayDay - 10 <= 5;
--------------- -------- ------------
| roomNum | owner | rentPayDay |
--------------- -------- ------------
| xxxC-906 | John | 15 |
| xxxxx-908 | Doe | 10 |
--------------- -------- ------------
2 rows in set (0.00 sec)
НО, когда я минус значение, которое может быть больше, чем некоторые значения rentPayDay, например:
mysql> select roomNum, owner, rentPayDay from t_room where rentPayDay - 11 <= 5;
что-то пошло не так, как это:
ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(`dev_learn`.`t_room`.`rentPayDay` - 11)'
У кого-нибудь есть какие-либо идеи по этому поводу? почему данные TINYINT не могут минус большее числовое значение в предложении where?
Комментарии:
1.
tinyint unsigned
означает, что он не может содержать отрицательные (ниже 0) значения. Если ваше вычитание приводит к отрицательному значению, это вызывает эту ошибку.2.
where rentPayDay - 11 <= 5
Никогда не используйте такие условия. Это запрещает использование индекса и вызывает полное сканирование таблицы. По возможности преобразуйте выражение условия в форму{column} {operator} {constant expression}
, в которой выражение будет вычисляться во время построения плана выполнения — один раз за весь запрос. Т.е. Выражение должно выглядетьwhere rentPayDay <= 5 11
дополнительно — проблема с «вне диапазона» не возникнет.3. @Akina ответ покажите мне способ решения проблемы. Возможно, благодаря вам и вашим напоминаниям.
4. Ответ @KenWhite, я не нашел ни одной ссылки, но я предполагаю
{rentPayDay - 11}
, что экспресс должен следовать тому же ограничению, что и определение rentPayDay. лучшим и безопасным способом должно быть сравнение rentPayDay с каким-либо другим вычисляемым значением.
Ответ №1:
An UNSIGNED TINYINT
имеет диапазон 0-255, и отрицательные значения не могут быть выражены в нем.
Если вы получаете ошибки приведения, рассмотрите:
SELECT * FROM rooms WHERE CAST(rentPayDay AS DECIMAL) - 11 <= 5;
Как показано здесь .
Комментарии:
1. к сожалению, это не решило мою проблему. Большое вам спасибо.
2. Не удается решить. Сначала выполняется вычитание, а не функция. Из-за типа операнда он выполняется как вычисление без знака — и отрицательный результат вызывает ошибку.
3. Я попробовал новый подход. Удивительно раздражает исправление.
4. @Akina показывает правильное направление для этого. моя проблема решается следующим образом: выберите номер комнаты, владельца, rentPayDay из t_room where (rentPayDay >= ИЗВЛЕЧЬ (ДЕНЬ С СЕГОДНЯШНЕГО ДНЯ ())) И (rentPayDay <= ИЗВЛЕЧЬ (ДЕНЬ С ЭТОГО МОМЕНТА()) 5);
5. Это еще одно решение, позволяющее избежать вычитания.
Ответ №2:
со ссылкой на @Akina и @Ken White, вот мое предположение об этой ошибке:
the express {columnName OPERATOR -value-} still be restricted as a whole with the same definition of {columnName}.
Я не знаю, почему и что произошло в ответе MySQL’e на мой запрос.
Лучший способ решить эту проблему:
please refer to @Akina comment under my original question post.
Большое спасибо всем, кто заботится и помогает.