PostgreSQL에서 평균 소수점 2자리로 반올림하는 방법은 무엇입니까?
나는 Postgre를 사용하고 있습니다.Ruby gem 'sequel'을 통한 SQL.
소수점 이하 두 자리로 반올림하려고 합니다.
내 코드는 다음과 같습니다.
SELECT ROUND(AVG(some_column),2)
FROM table
다음 오류가 발생합니다.
PG::Error: ERROR: function round(double precision, integer) does
not exist (Sequel::DatabaseError)
다음 코드를 실행하면 오류가 발생하지 않습니다.
SELECT ROUND(AVG(some_column))
FROM table
내가 뭘 잘못하고 있는지 아는 사람?
이 Postgre를 정의하지 SQL이 정의하지 않음round(double precision, integer)
@Mike Sherrill 'Cat Recall'이 댓글에서 설명하는 이유로, 정밀도를 취하는 라운드의 버전은 다음과 같은 경우에만 사용할 수 있습니다.numeric
.
regress=> SELECT round( float8 '3.1415927', 2 );
ERROR: function round(double precision, integer) does not exist
regress=> \df *round*
List of functions
Schema | Name | Result data type | Argument data types | Type
------------+--------+------------------+---------------------+--------
pg_catalog | dround | double precision | double precision | normal
pg_catalog | round | double precision | double precision | normal
pg_catalog | round | numeric | numeric | normal
pg_catalog | round | numeric | numeric, integer | normal
(4 rows)
regress=> SELECT round( CAST(float8 '3.1415927' as numeric), 2);
round
-------
3.14
(1 row)
에서 (으)는 다음과 같습니다.float8
의 단축 별칭일 뿐입니다.double precision
당신은 포스트그리를 볼 수 있습니다.SQL이 출력에서 확장하고 있습니다.
을 반림할올팅캐야해합니다스값을합다니▁you▁to▁the▁to▁cast▁must.numeric
두 개의 단어로 이루어진 형태를 사용하다round
추가하기만 하면 됩니다.::numeric
는 기출연위해서을마치, 진속치,.round(val::numeric,2)
.
에는 사용하지 round
.사용하다to_char
(설명서의 데이터 형식 지정 기능 참조). 이 기능을 사용하면 형식을 지정하고text
을 해도입니다.numeric
를 들어 다음과 같습니다예:
regress=> SELECT to_char(float8 '3.1415927', 'FM999999999.00');
to_char
---------------
3.14
(1 row)
to_char
형식 지정의 일부로 숫자를 반올림합니다. 그FM
접두사가 알려줍니다.to_char
앞에 공백이 있는 패딩을 원하지 않는다는 것입니다.
((이것은 Wiki입니다! 향상시키려면 편집하십시오!)
캐스팅을 위한 오래된 구문도 시도해 보십시오.
SELECT ROUND( AVG(some_column)::numeric, 2 ) FROM table;
모든 버전의 Postgre와 함께 작동합니다.SQL.
...그러나 최종 솔루션으로서 ROUUND 기능을 오버로드할 수 있습니다.
주조 전략으로 과부하 발생
CREATE FUNCTION ROUND(float,int) RETURNS NUMERIC AS $f$
SELECT ROUND( CAST($1 AS numeric), $2 )
$f$ language SQL IMMUTABLE;
이제 사용자의 지침이 제대로 작동합니다. 다음과 같이 전체 비교해 보십시오.
SELECT trunc(n,3), round(n,3) n_round, round(f,3) f_round,
pg_typeof(n) n_type, pg_typeof(f) f_type, pg_typeof(round(f,3)) f_round_type
FROM (SELECT 2.0/3.0, 2/3::float) t(n,f);
자르기 | n_둥근의 | f_둥근의 | n_타입 | f_타입 | f_원형_타입 |
---|---|---|---|---|---|
0.666 | 0.667 | 0.667 | 숫자의 | 2배 정밀도 | 숫자의 |
ROUUND(플로트,int) 기능은 다음과 같습니다.f_round
데이터 유형을 하며, 는 일부 응용 solved! ( 해결됨) 소자을반환하며유형해문일, 프는서제에결램로그응용부!
다른 애플리케이션에서도 결과적으로 플로트가 필요합니다.다른 방법은 다음과 같습니다.round(f,3)::float
또는 를 생성합니다.round_tofloat()
기능타. 안대, 하부과ROUND
함수를 다시 사용하고 부동 소수점 번호의 모든 정확도 범위를 사용하는 것은 정확도가 정의될 때 부동 소수점을 반환하는 것입니다(이언 케니의 답변 참조).
CREATE FUNCTION ROUND(
input float, -- the input number
accuracy float -- accuracy, the "counting unit"
) RETURNS float AS $f$
SELECT ROUND($1/accuracy)*accuracy
$f$ language SQL IMMUTABLE;
해라
SELECT round(21.04, 0.05); -- 21.05 float!
SELECT round(21.04, 5::float); -- 20
SELECT round(1/3., 0.0001); -- 0.3333
SELECT round(2.8+1/3., 0.5); -- 3.15
SELECT round(pi(), 0.0001); -- 3.1416
: 명령 \df round
psql
표와 .
스키마 | 이름 | 결과 | 인수------------+-------+---------+------------------my schema | 라운드 | 숫자 | float, int.나의 계획.pg_float | 라운드 | 플로트 | 플로트pg_sigma | 원형 | 숫자 | 숫자pg_sigma | 원형 | 숫자 | 숫자, int
float가 의 동의어인 경우double precision
그리고 저의 계획은public
스키마를 사용하지 않는 경우. 그pg_catalog
함수는 기본 함수입니다. 자세한 내용은 내장 함수 안내를 참조하십시오.
반올림 및 포밍
그to_char
함수는 라운드 프로시저를 내부적으로 적용하므로 터미널에서 최종 결과만 표시하는 것이 목표일 때는 수식어를 숫자 형식 패턴의 접두사로 사용할 수 있습니다.
SELECT round(x::numeric,2), trunc(x::numeric,2), to_char(x, 'FM99.99')
FROM (SELECT 2.0/3) t(x);
둥그런 | 자르기 | to_char |
---|---|---|
0.67 | 0.66 | .67 |
메모들
문제의 원인
일부 Postgre에 과부하가 부족합니다.SQL 함수, 이유(??: "부족하다"(!)고 생각하지만, @CraigRinger, @Catcall and the PostgreSQL 팀은 "pg의 역사적 근거"에 대해 동의합니다.
성능 및 재사용에 대한 참고 사항
pg_catalog의 ROUUND와 같은 내장 함수는 직접 캐스트 인코딩과 비교할 때 성능 손실 없이 오버로드될 수 있습니다.고성능을 위해 사용자 정의 캐스트 기능을 구현할 때는 다음 두 가지 주의 사항을 준수해야 합니다.
그
IMMUTABLE
이와 같은 코드 스니펫에 대해 절은 매우 중요한데, 이는 가이드에 언급된 바와 같이 "최적화 프로그램이 지속적인 인수로 함수를 호출할 때 함수를 사전 평가할 수 있도록 허용"하기 때문입니다.PLpgSQL은 "순수 SQL"을 제외하고 선호되는 언어입니다.JIT 최적화의 경우(때로는 병렬화의 경우도 있음)
language SQL
더 나은 최적화를 얻을 수 있습니다.함수 호출을 사용하는 대신 작은 코드 조각을 복사/붙여넣기하는 것과 같습니다.
의 것: 위의 것: 위의 것.ROUND(float,int)
함수는 최적화 후 @CraigRinger의 답변보다 매우 빠르며, 동일한 내부 표현으로 컴파일됩니다.Postgre의 표준은 아니지만,SQL은 pg_pubLib와 같은 재사용 가능한 중앙 집중식 "스니펫 라이브러리"에 의해 프로젝트의 표준이 될 수 있습니다.
n번째 비트 또는 다른 숫자 표현으로 반올림
일부 사람들은 포스트그리어에게 말이 안 된다고 주장합니다.부동 소수점 데이터 유형을 반올림하기 위한 SQL. 부동 소수점은 이진 표현이므로 비트 수 또는 16진수 표현을 반올림해야 합니다.
그럼, 문제를 해결해보죠. 이국적인 제안을 덧붙이자면...여기서의 목적은 다른 오버로드 함수의 플로트 유형을 반환하는 것입니다.
ROUND(float, text, int) RETURNS float
그text
둘 중 하나를 선택하는 것입니다.
'dec'
'의 자유 '의 자유','bin'
" 과 "당을위표" 현해그리고상그▁"리▁for고위▁and"ation.'hex'
16진수 표현에 사용됩니다.
그래서, 다른 표현에서 우리는 반올림할 자리의 수에 대해 다른 해석을 합니다.소수점 또는 16진수 대신 이진 숫자를 디스커션할 때 "분수 자리"(원래 d자리보다)가 적은 숫자 x를 대략적으로 더 짧은 값으로 반올림하면 더 짧아집니다.
"순수 SQL"을 사용하는 C++ 없이는 쉽지 않지만, 이 코드 스니펫은 다음을 설명하고 해결 방법으로 사용할 수 있습니다.
-- Looking for a round_bin() function! this is only a workaround:
CREATE FUNCTION trunc_bin(x bigint, t int) RETURNS bigint AS $f$
SELECT ((x::bit(64) >> t) << t)::bigint;
$f$ language SQL IMMUTABLE;
CREATE FUNCTION ROUND(
x float,
xtype text, -- 'bin', 'dec' or 'hex'
xdigits int DEFAULT 0
)
RETURNS FLOAT AS $f$
SELECT CASE
WHEN xtype NOT IN ('dec','bin','hex') THEN 'NaN'::float
WHEN xdigits=0 THEN ROUND(x)
WHEN xtype='dec' THEN ROUND(x::numeric,xdigits)
ELSE (s1 ||'.'|| s2)::float
END
FROM (
SELECT s1,
lpad(
trunc_bin( s2::bigint, CASE WHEN xd<bin_bits THEN bin_bits - xd ELSE 0 END )::text,
l2,
'0'
) AS s2
FROM (
SELECT *,
(floor( log(2,s2::numeric) ) +1)::int AS bin_bits, -- most significant bit position
CASE WHEN xtype='hex' THEN xdigits*4 ELSE xdigits END AS xd
FROM (
SELECT s[1] AS s1, s[2] AS s2, length(s[2]) AS l2
FROM (SELECT regexp_split_to_array(x::text,'\.')) t1a(s)
) t1b
) t1c
) t2
$f$ language SQL IMMUTABLE;
해라
SELECT round(1/3.,'dec',4); -- 0.3333 float!
SELECT round(2.8+1/3.,'dec',1); -- 3.1 float!
SELECT round(2.8+1/3.,'dec'); -- ERROR, need to cast string
SELECT round(2.8+1/3.,'dec'::text); -- 3 float
SELECT round(2.8+1/3.,'dec',0); -- 3 float
SELECT round(2.8+1/3.,'hex',0); -- 3 float (no change)
SELECT round(2.8+1/3.,'hex',1); -- 3.1266
SELECT round(2.8+1/3.,'hex',3); -- 3.13331578486784
SELECT round(2.8+1/3.,'bin',1); -- 3.1125899906842625
SELECT round(2.8+1/3.,'bin',6); -- 3.1301821767286784
SELECT round(2.8+1/3.,'bin',12); -- 3.13331578486784
그리고.\df round
또한 다음이 있습니다.
Schema | Name | Result | Argument
------------+-------+---------+---------------
myschema | round | float | x float, xtype text, xdigits int DEFAULT 0
사용해 보십시오.
SELECT to_char (2/3::float, 'FM999999990.00');
-- RESULT: 0.67
간단히 말하면:
SELECT round (2/3::DECIMAL, 2)::TEXT
-- RESULT: 0.67
아래의 기능을 사용할 수 있습니다.
SELECT TRUNC(14.568,2);
결과는 다음과 같습니다.
14.56
원하는 유형에 변수를 캐스팅할 수도 있습니다.
SELECT TRUNC(YOUR_VAR::numeric,2)
SELECT ROUND(SUM(amount)::numeric, 2) AS total_amount
FROM transactions
선물: 200234.08
열을 다음과 같은 숫자로 캐스팅해 보십시오.
SELECT ROUND(cast(some_column as numeric),2) FROM table
브라이언의 응답에 따라 쿼리에서 소수점 이하를 제한할 수 있습니다.km/h에서 m/s로 변환해서 dygraph로 표시하는데 dygraph로 해보니 이상하게 보입니다.대신 쿼리에서 계산을 수행하면 문제가 없어 보입니다.이것은 postgresql 9.5.1에 있습니다.
select date,(wind_speed/3.6)::numeric(7,1) from readings;
오류: 함수 반올림(이중 정밀도, 정수)이 존재하지 않습니다.
솔루션:유형 캐스트를 추가해야 작동합니다.
예:round(extract(second from job_end_time_t)::integer,0)
언급URL : https://stackoverflow.com/questions/13113096/how-to-round-an-average-to-2-decimal-places-in-postgresql
'programing' 카테고리의 다른 글
비동기 코루틴으로 동기 함수를 래핑하려면 어떻게 해야 합니까? (0) | 2023.05.01 |
---|---|
이클립스의 모든 파일에서 문자열 바꾸기 (0) | 2023.05.01 |
정렬 목록과 정렬된 사전의 차이점은 무엇입니까? (0) | 2023.05.01 |
HttpContent 사용 방법을 찾을 수 없습니다. (0) | 2023.05.01 |
일반 이전 CLR 개체 대 데이터 전송 개체 (0) | 2023.05.01 |