Округление в SQL Server? - PullRequest
       4

Округление в SQL Server?

9 голосов
/ 18 ноября 2010

Я написал систему подкачки для сервера SQL.и это прекрасно работает, но я пытаюсь вернуть, сколько страниц в общей сложности

Следовательно, если есть 5 записей и 2 записи на странице, то в общей сложности 3 страницы

это то, что яиметь

   SELECT @TotalPages = ( (SELECT COUNT(*) FROM #TempItems) / @RecsPerPage )

и мой выходной параметр определен так:

   @TotalPages AS INT OUT,

Теперь это вроде работает :-) В моем тесте есть 5 записей и 2 записи на страницу, поэтому вышеselect возвращает 2, но это неправильно, это должно быть 3

Это потому, что его поговорка 5/2 = целое число 2 ... как мне округлить ...?

Я устал потолок, ноне удалось заставить его работать ..

Есть идеи?

Заранее спасибо

Ответы [ 8 ]

13 голосов
/ 18 ноября 2010

Пробовали ли вы приводить числитель и знаменатель как число с плавающей точкой, а затем использовать Cieling?

Целочисленные операции всегда дают целые числа. Попробуйте следующее -

SELECT @TotalPages = CEILING((SELECT cast(COUNT(*) as float) FROM #TempItems) / @RecsPerPage ) 
5 голосов
/ 18 ноября 2010

Вы можете использовать целочисленную арифметику для этого:

SELECT @TotalPages = ((SELECT COUNT(*) FROM #TempItems) + @RecsPerPage - 1) / @RecsPerPage

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

3 голосов
/ 18 ноября 2010

SQL Server всегда будет давать целочисленный результат при делении двух целых чисел.

Вы можете добавить «.0» в конец фактических жестко закодированных значений или умножить на «1,0», чтобы преобразоватьзначение поля.Если вы хотите округлить, то лучший способ, который я знаю, это добавить 0,5, а затем вызвать обычную функцию ROUND.Это работает, потому что ROUND_DOWN (число + .5) всегда совпадает с ROUND_UP (число).

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

Нообратите внимание, что

round(1.0 / 2.0,0)

вернет результат с плавающей запятой , тогда как

round(cast(1 as float) / cast(2 as float),0)

даст результат integer .Так что используйте тот, который лучше всего подходит для вас.

Все это проиллюстрировано в следующем примере:

SELECT
  ROUND(5/2,0) AS INTEGER_EXAMPLE
 ,ROUND((5.0 / 2.0),0) AS FLOATING_POINT_EXAMPLE
 ,ROUND(CAST(5 AS FLOAT) / CAST(2 AS FLOAT),0) AS CASTING_EXAMPLE
 ,ROUND((5 * 1.0) / (2 * 1.0),0) AS CONVERTED_TO_FP_EXAMPLE
 ,ROUND(((1 * 1.0) / (4 * 1.0)) + (1.0 / 2.0),0) AS ROUNDED_UP_EXAMPLE

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

create function roundup(@n float) returns float
as
begin
  --Special case: if they give a whole number, just return it
  if @n = ROUND(@n,0)
    return @n;

  --otherwise, add half and then round it down
  declare @result float = @n;
  declare @half float = (1.0 / 2.0);
  set @result = round(@n + @half,0);

  return @result;
end

select
  dbo.roundup(0.0) as example_0
 ,dbo.roundup(0.3) as example_pt_three
 ,dbo.roundup(0.5) as example_pt_five
 ,dbo.roundup(0.9) as example_pt_nine
3 голосов
/ 18 ноября 2010

Целочисленная математика не округляется, она усекается. Измените @RecsPerPage на число с плавающей точкой вместо int, а затем используйте ceil в выражении sql.

0 голосов
/ 23 сентября 2011

Сохраните исходную формулу, но вам нужно проверить, является ли остаток> 0, и если да, просто добавьте 1 к вашему результату.

0 голосов
/ 19 ноября 2010
DECLARE @Count int
SELECT @Count = COUNT(*) FROM #TempItems
SELECT @TotalPages = @Count / @RecsPerPage 
IF @Count % @RecsPerPage > 0 SET @TotalPages = @TotalPages +1
0 голосов
/ 18 ноября 2010

Вот какой-то похожий код.Функции CAST удерживают SQL от автоматического округления.Отрегулируйте 0,00 с точностью, которую вы хотите.

declare @C int
declare @D int

SET @C = 5
SET @D = 2

DECLARE @Answer FLOAT

SELECT @Answer = CAST(@C as FLOAT) / CAST(@D as FLOAT)

SET @Answer = CASE WHEN @Answer - ROUND(@Answer, 0) > 0.00 THEN ROUND(@Answer, 0) + 1
                   ELSE ROUND(@Answer, 0) END

PRINT @Answer

edit - правильный параметр округления.до 0

0 голосов
/ 18 ноября 2010

Попробуйте

SELECT @TotalPages = CEILING( (SELECT COUNT(*) FROM #TempItems) * 1.0/ @RecsPerPage ) 
...