Я намагаюся розділити два стовпці у операторі 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()
на дільнику.