/ / Округлення частки поділу? - sql, postgresql, округлення

Округлення частки дивізії? - sql, postgresql, округлення

Я намагаюся розділити два стовпці у операторі select, а потім округлю частково до 4 знаків після коми.

select round(round(sum(case when acct_no = "2999"
and date between "1/1/14" and current_date then amount end)::numeric, 4)::float
/ round(sum(case when acct_no = "3989"
and date between "1/1/14" and current_date then amount end)::numeric, 4)::numeric, 4) column
from table

Решта запитів буде мати декілька дат, тому дати в них повинні бути необхідними.

Помилка, яку він надає:

ПОМИЛКА: функція round (подвійна точність, ціле число) не існує

Це було зроблено в PostgreSQL.

Відповіді:

3 для відповіді № 1

Я повторно відформатував ваш приклад коду, щоб спробувати зрозуміти його:

select  round(
round(
sum(
case
when    acct_no = "2999"
and date between "1/1/14" and current_date then amount
end )::numeric,
4 )::float
/ round(
sum(
case
when    acct_no = "3989"
and date between "1/1/14" and current_date then amount
end )::numeric,
4 )::numeric,
4 ) column
from table

Проблема полягає в тому, що ви ставите чисельник вашої операції підрозділу як float тип даних, яка, оскільки ви не вказали точність, еквівалентна double precision.

round(
sum(
case
when    acct_no = "2999"
and date between "1/1/14" and current_date then amount
end )::numeric,
4 )::float
/ round(
sum(
case
when    acct_no = "3989"
and date between "1/1/14" and current_date then amount
end )::numeric,
4 )::numeric

Таким чином, результат виразу a double precision значення замість a numeric значення, отже, ви спостерігали помилку.


4 для відповіді № 2
SELECT round((
sum(CASE WHEN acct_no = "2999"
AND thedate between "2014-1-1" AND current_date THEN amount END)
/ sum(CASE WHEN acct_no = "3989"
AND thedate between "2014-1-1" AND current_date THEN amount END)
)::numeric, 4) AS result
FROM   tbl;
  • Немає функції round() з доданим модифікатор точності для типів з плаваючою точкою в Postgres. Лише для numeric, відповідно до документації.

  • Розділення числа з плаваючою точкою на numeric призводить до double precision (float8). Тест:

    SELECT 5::float/3::numeric  -- result is double precision
    
  • Круглий один раз в кінці розрахунку. Це швидше і точніше.

  • Ніколи не використовуйте date як ім'я стовпця. Це зарезервоване слово в стандартному SQL і базовий тип у Postgres.

  • Найкраще використовувати рекомендований формат дати ISO 8601 у літералах дат у вашому коді. Це працює незалежно від налаштувань і локалі, тоді як локальний формат розривається з різними налаштуваннями.

Якщо це не було для rest of the query Ви згадали, це може бути спрощене далі:

SELECT round((   sum(CASE WHEN acct_no = "2999" THEN amount END)
/ NULLIF(sum(CASE WHEN acct_no = "3989" THEN amount END), 0)
)::numeric, 4) AS result
FROM   tbl
WHERE  thedate between "2014-1-1"::date AND current_date;

Нарешті, це також вловлює "поділ на 0" за винятком використання NULLIF() на дільнику.