Ответ 1
Недавно я столкнулся с этим и нашел наиболее разумное решение просто использовать любые UNSIGNED ints как SIGNED.
SELECT *, ((1 / log(1301980250 - cast(date as signed)) * 175) as weight FROM news_articles ORDER BY weight
Я получаю сообщение об ошибке
Значение BIGINT UNSIGNED находится вне допустимого диапазона в '(1301980250 -
mydb
.news_articles
.date
)'
Когда я запускаю запрос
SELECT *, ((1 / log(1301980250 - date)) * 175) as weight FROM news_articles ORDER BY weight;
Удаление условия ORDER BY также устраняет ошибку. Как я могу это исправить?
Обновление: Поле даты содержит временную метку unix (например: 1298944082). Ошибка начала появляться после обновления MySQL с 5.0.x до 5.5.x
Любая помощь пожалуйста?
Недавно я столкнулся с этим и нашел наиболее разумное решение просто использовать любые UNSIGNED ints как SIGNED.
SELECT *, ((1 / log(1301980250 - cast(date as signed)) * 175) as weight FROM news_articles ORDER BY weight
Проблема вызвана переполнением целых чисел без знака, как предложено wallyk. Его можно решить с помощью
SELECT *, ((1 / log((date - 1301980250) * -1)) * 175) as weight FROM news_articles ORDER BY weight;
(этот работал у меня)
`NO_UNSIGNED_SUBTRACTION
(не проверено)Любое значение даты после 2011-04-04 22:10:50 PDT (2011-04-05 05:10:50 utc) приведет к этой ошибке, поскольку это сделает выражение отрицательным.
Иногда это может быть вызвано нулями в данных.
Используйте IFNULL для установки значения по умолчанию (вероятно, 0 для отметки времени является плохим значением по умолчанию, и фактически в этом случае вам может быть лучше исключить и нулевые даты в предложении WHERE)
SELECT (123456 - IFNULL(date, 0)) AS leVar
возможно, вы можете использовать cast
SELECT *, ((1 / log(1301980250 - cast(date AS SIGNED))) * 175) as weight FROM news_articles ORDER BY weight;
Никто не упомянул, что функция log() определена только для строго положительных аргументов. Следите за этим при использовании вычитаний внутри log().
Что касается первоначального вопроса, ключевым фактором для разрешения было сообщить нам тип данных для столбца даты. Если он не подписан, MySQL может не понравиться.
Правило состоит в том, что MySQL имеет плохой арифметический алгоритм и не может понять, как вычесть операнд B из другого A (= do AB), когда A закодирован на меньшем количестве байтов, чем B AND B> A.
например, A = 12 и SMALLINT, B = 13 AS INT, тогда MySQL не может понять, что такое AB (-1!)
Чтобы сделать контент MySQL, просто увеличьте длину кода операнда А. Как? Использование CAST() или умножение A на десятичное число.
Как можно видеть, это не проблема переполнения, а проблема обработки знака в арифметике MySQL. Микропроцессор, а точнее, человек, не имеет проблем с выполнением такого рода арифметики...
Использование CAST() - это способ или, для краткости, просто провоцирование неявного приведения путем умножения операнда A на 1. (или 1.0):
например
1.*A - B
Я только что столкнулся с этой проблемой, делая обновление на поле, где результат оказался меньше 0.
Решение. Убедитесь, что ни одно из ваших обновлений не приводит к тому, что ваш результат будет меньше 0 в поле без знака.