Sql round не работает

Почему округление до сотых при помощи ROUND() в MySQL округляет вниз?

Выполняю запрос к БД MySQL, чтобы получить проценты за платеж:

Вопрос: почему округление до сотых округляет вниз, хотя на конце цифра 5?

При этом запрос select round(75.725, 2) округляет всё корректно — до 75.73.
Тип столбца percent в таблице как double .

1 ответ 1

почему округление до сотых округляет вниз, хотя на конце цифра 5?

Тип столбца percent в таблице как double.

Тип DOUBLE относится к т.н. «неточным» типам данных — т.е. используемое для его хранения двоичное представление не в точности равно введённому, а лишь максимально близко к нему. Как итог — печально известные 0,1000000001 или 0,0999999999 вместо введённого изначально 0,1. И false при сравнении такого значения с непосредственно заданным в виде литерала значением 0,1.

В соответствии с документацией для таких типов данных

For approximate-value numbers, the result depends on the C library. On many systems, this means that ROUND() uses the “round to nearest even” rule: A value with a fractional part exactly halfway between two integers is rounded to the nearest even integer.

или, если по-русски, «результат округления зависит от используемой библиотеки функций, во многих случаях выполняется округление к ближайшему чётному» (т.н. «бухгалтерское» округление).

Для того, чтобы получить округление «половина — вверх», необходимо привести сначала имеющееся значение к «точному» числовому типу, т.е. желаемое округление можно было бы получить так:

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

При этом запрос select round(75.725, 2) округляет всё корректно — до 75.73.

В данном случае константа-литерал сразу создаётся с типом DECIMAL. Потому и округление работает, как указано в той же документации:

For exact-value numbers, ROUND() uses the “round half away from zero” or “round toward nearest” rule: A value with a fractional part of .5 or greater is rounded up to the next integer if positive or down to the next integer if negative. (In other words, it is rounded away from zero.) A value with a fractional part less than .5 is rounded down to the next integer if positive or up to the next integer if negative.

или, если по-русски, «округление к ближайшему целому в направлении от нуля», т.е. положительные — вверх, а отрицательные — вниз.

PS. Обратите внимание — функции преобразования типа CAST() и CONVERT() вообще не предусматривают приведения числа к неточному числовому типу.

Источник

Ошибка в функции ROUND/RAND

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

Читайте также:  Как настроить эффект перехода

ROUND() в хранимой функции
Всем привет! Столкнулся с такой непонятно штукой. Создал хранимую функцию: CREATE FUNCTION.

Некорректная работа функции round
Доброго времени суток! После подключения phpexcel не верно работает функция round(). 2

но данные вы вводите а где в то GUI.

обычно пишут функцию типа ADDUser(FIO,хх1, хх2. )
вызывают ее из формы и получают только результат, а в самой функции уже идут проверки

а если в имени уже есть 10 символов? получается 11-12

и как искать повторения? ведь если мы ввели Oleeeeeeeg, то в базе будет Oleeeeeeeg9 и в следующий раз Oleeeeeeeg тоже может превратиться в Oleeeeeeeg9

ИМХО задача неправильно сформулирована

В SQL Server Management Studio (SSMS). Ну вот функция проверки есть. Но не работает. А проверка как я понимаю просто по именам типо если олег1 есть ему предложат олег2. Просто часть базы идет через код как обычно пару записей, омстальные через форму, ну там изменить первые 200 записей и вводить данные. Вот пример как только возраст ввожу меньше 10 то сразу еррор выдает и не дает записать

Добавлено через 27 минут
Или я про натупил и это нужно в тригере писать . Но если да же в тригере явно выдаст ошибку. Да сделать хотя бы что бы +1 к имени писало. Проверку уже сам как нить напишу. Спасибо

Добавлено через 5 часов 45 минут
qwertehok, Переделал в тригер, сьедат а вот результата не видно (((

Источник

Почему округление до сотых при помощи ROUND() в MySQL округляет вниз?

Выполняю запрос к БД MySQL, чтобы получить проценты за платеж:

Вопрос: почему округление до сотых округляет вниз, хотя на конце цифра 5?

При этом запрос select round(75.725, 2) округляет всё корректно — до 75.73.
Тип столбца percent в таблице как double .

1 ответ 1

почему округление до сотых округляет вниз, хотя на конце цифра 5?

Тип столбца percent в таблице как double.

Тип DOUBLE относится к т.н. «неточным» типам данных — т.е. используемое для его хранения двоичное представление не в точности равно введённому, а лишь максимально близко к нему. Как итог — печально известные 0,1000000001 или 0,0999999999 вместо введённого изначально 0,1. И false при сравнении такого значения с непосредственно заданным в виде литерала значением 0,1.

В соответствии с документацией для таких типов данных

For approximate-value numbers, the result depends on the C library. On many systems, this means that ROUND() uses the “round to nearest even” rule: A value with a fractional part exactly halfway between two integers is rounded to the nearest even integer.

или, если по-русски, «результат округления зависит от используемой библиотеки функций, во многих случаях выполняется округление к ближайшему чётному» (т.н. «бухгалтерское» округление).

Для того, чтобы получить округление «половина — вверх», необходимо привести сначала имеющееся значение к «точному» числовому типу, т.е. желаемое округление можно было бы получить так:

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

При этом запрос select round(75.725, 2) округляет всё корректно — до 75.73.

В данном случае константа-литерал сразу создаётся с типом DECIMAL. Потому и округление работает, как указано в той же документации:

For exact-value numbers, ROUND() uses the “round half away from zero” or “round toward nearest” rule: A value with a fractional part of .5 or greater is rounded up to the next integer if positive or down to the next integer if negative. (In other words, it is rounded away from zero.) A value with a fractional part less than .5 is rounded down to the next integer if positive or up to the next integer if negative.

или, если по-русски, «округление к ближайшему целому в направлении от нуля», т.е. положительные — вверх, а отрицательные — вниз.

Читайте также:  После получения диплома если не работать сколько он будет действовать

PS. Обратите внимание — функции преобразования типа CAST() и CONVERT() вообще не предусматривают приведения числа к неточному числовому типу.

Источник

Функции ROUND, CEILING, FLOOR в SQL: округление и другие действия с дробными числами

Оглавление

  • Функция SQL ROUND
  • Функция SQL CEILING
  • Функция SQL FLOOR

Связанные темы

  • Оператор SELECT
  • Агрегатные функции
Назад >>

Функция SQL ROUND

Функция SQL ROUND(результат_вычислений, n) округляет результат вычислений до n-го знака после запятой. Округление производится по правилам арифметики.

Если n — отрицательное число (−n), то округление происходит до n-го знака перед запятой. Таким образом, с помощью функции ROUND можно получить и целое число как результат округления.

Пример 1. В базе данных фирмы есть таблица Staff, содержащая данные о сотрудниках фирмы. Выведем индивидуальные размеры заработной платы сотрудников:

Результатом выполнения запроса будет следующая таблица:

Name Salary
Sanders 18357.5
Pernal 15430.0
Marenghi 17506.8
Doctor 12322.8
Factor 16228.7
Junkers 16232.8
Moonlight 21500.6
Aisen 19540.7
MacGregor 15790.8

Для вычисления среднего размера заработной платы пишем запрос:

Получим следующий результат:

AVG(Salary)
16990.06662326389

Для отчётов результат с таким числом знаков после запятой не годится. Округлим результат до второго знака после запятой с помощью функции ROUND:

Результат будет следующим:

Avg_Salary
16990.07

Пример 2. Теперь округлим результат до первого знака до запятой, применяя в функции ROUND параметр минус единица:

Результат будет следующим:

Avg_Salary
16990

Сместим округление ещё на один знак влево и применим в функции ROUND параметр минус 2:

Результат будет следующим:

Avg_Salary
17000

Функция SQL ROUND может применяться ещё и с третьим необязательными параметром (кроме MySQL). Если этим параметром будет 1, то округление производиться не будет, просто в результате будет оставлено столько знаков после запятой, сколько указано во втором параметре.

Пример 3. Оставить в результате вычислений средней заработной платы два знака после запятой, не производя округления. Применяем функцию ROUND с тремя параметрами:

Результат будет следующим:

Avg_Salary
16990.06

Функция MySQL TRUNCATE

В MySQL аналогом разновидности функции ROUND без округления результата является функция TRUNCATE. Она, как и ROUND в общем случае имеет два параметра: результат вычислений и число знаков после запятой.

Пример 4. Условие то же, что в примере 3, но в MySQL. Применяем функцию TRUNCATE:

Читайте также:  Не работает подсветка магнитолы хендай солярис

Получим результат без округления, как в предыдущем примере:

Avg_Salary
16990.06

Функция SQL CEILING

Функция SQL CEILING не производит округления. Она просто принимает дробное число и возвращает максимальное целое число, не меньшее принятого. Приведём примеры действия функции с различными принятыми дробными числами.

Функция с аргументом Возвращаемое значение
CEILING(0.38) 1
CEILING(1.63) 2
CEILING(−0.38) 0
CEILING(−1.63) −1

В случае функции CEILING некорректно говорить об округлении, поскольку она преобразует числа без учёта правил арифметики.

Функция SQL FLOOR

Функция FLOOR также не производит округления. Её действие противоположно действию функции CEILING. Она принимает дробное число и возвращает максимальное целое число, не большее принятого. Приведём примеры действия функции с различными принятыми дробными числами.

Функция с аргументом Возвращаемое значение
FLOOR(0.38) 0
FLOOR(1.63) 1
FLOOR(−0.38) −1
FLOOR(−1.63) −2

Функция FLOOR, как и функция CEILING, преобразует числа без учёта правил арифметики.

Источник

SQL Server ROUND() не работает для FLOAT, заканчивающегося на 1

Я поменял свой пример на использование FLOAT. слишком много людей повесились на всю вещь NVARCHAR. Мы не храним цифры в базе данных как NVARCHAR. Я просто использовал NVARCHAR в качестве примера. Я получаю те же результаты с FLOAT.

У нас возникают проблемы с SQL Server ROUND() для некоторых FLOAT

Сначала возвращается: 1.327809
Второй возвращается: 1.32782

Вы думаете, что первый из них вернет 1.32781, а не 1.327809.

Является ли это признаком или ошибкой в ​​ROUND? Любой простой способ обойти это?

Основываясь на идее Mat о том, чтобы отличить их как DECIMAL, это работает. это уродливо, но работает. Причина, по которой я использую 10, я просматриваю в нашей базе данных, и это, кажется, самый длинный номер, который мы храним. Также мне нужно преобразовать его обратно в FLOAT, потому что они не хотят видеть никаких завершающих 0

Попробуйте этот запрос.

Это указывает на то, что ROUND() неявно бросает ваши значения VARCHAR в FLOAT перед их усечением.

И поскольку FLOAT не могут точно представлять 1.327810, вы на самом деле обрезаете 1.3278099999999 (или что-то подобное).

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

Используйте ROUND(@var,6) вместо ROUND(@var,6,1) . В функции ROUND() есть третий необязательный параметр, и похоже, что он здесь не нужен.

Сейчас я оставлю это ниже, это правда, но это не причина проблемы op.

Правильный ответ — тот, который предоставляется MatBailie, — строка nVarChar преобразуется в float, а затем операция усечения сводит ее к следующему более низкому значению.

Выполняется ли тип операции. функция должна быть tinyint, smallint или int. Когда функция опущена или имеет значение 0 (по умолчанию), числовое выражение округляется. * Если указано значение, отличное от 0, числовое выражение вырезается. *

попробуйте, это показывает разницу:

тип вывода определяется входом. В этом случае вход «1.3278100», поэтому значение преобразуется в числовой тип данных с точностью, основанной на количестве значимых цифр в строке (‘ 1.3278100 ‘имеет 5 значащих цифр), поэтому тип вывода определяется как числовой (6,5) или что-то вроде этого. это вызывает неожиданное усечение. Это уже укусило меня.

Источник

Оцените статью