PostgreSQL में औसतन 2 दशमलव स्थानों पर गोल कैसे करें?


191

मैं रूबी मणि 'सीक्वल' के माध्यम से PostgreSQL का उपयोग कर रहा हूं।

मैं दो दशमलव स्थानों पर चक्कर लगा रहा हूँ।

यहाँ मेरा कोड है:

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

क्या कोई जानता है कि मुझसे क्या गलती हो रही है?


3
आपका त्रुटि संदेश आपके प्रश्न में कोड से मेल नहीं खाता है।
21:39 पर म्यू

सिंटैक्स त्रुटि एक तरफ, dba.SE पर यह बारीकी से संबंधित प्रश्न PostgreSQL में डबल सटीक संख्याओं को गोल करने पर कुछ प्रकाश डालता है।
इरविन ब्रान्डसेट्टर

@muistooshort, इस ओर इशारा करने के लिए धन्यवाद। इसे 'राउंड ’कहना चाहिए जहां इसे g एवीजी’ कहते हैं। संपादित।
23:16 पर user1626730

खोज परिणामों के लिए, मुझे संकेत से आउटपुट के रूप में यह संकेत भी मिलता है:HINT: No function matches the given name and argument types. You might need to add explicit type casts.
वेज़र

जवाबों:


264

PostgreSQL परिभाषित नहीं करता है round(double precision, integer)। कारणों के लिए @ माइक शेरिल 'कैट रिकॉल' टिप्पणियों में बताते हैं, राउंड का संस्करण जो सटीक लेता है वह केवल इसके लिए उपलब्ध है 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। आप देख सकते हैं कि PostgreSQL इसे आउटपुट में विस्तारित कर रहा है)।

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कि आप प्रमुख रिक्त स्थान के साथ किसी भी गद्दी नहीं करना चाहती।


हम्म। जब मैं कोशिश करता ROUND(CAST(FLOAT8 '3.1415927' AS NUMERIC),2);हूं, तो मुझे '0.314E1' मिलता है। और मेरे पास मेरा कोड लिखा हुआ है ROUND(AVG(val),2)फिर भी मुझे अपने प्रश्न में वर्णित त्रुटि मिलती है।
user1626730

मैं सिर्फ ROUND(CAST(FLOAT8 '3.1415927' AS NUMERIC),2);PgAdmin और रूबी पर भागा । PgAdmin के साथ, मुझे 3.14 मिलता है, लेकिन रूबी के साथ (वह Sequel रत्न का उपयोग करके) मुझे '0.314E1' मिलता है। मुझे आश्चर्य है कि ऐसा क्यों है ...
user1626730

12
"किसी विषम कारण से राउंड का संस्करण जो सटीक होता है, केवल संख्यात्मक के लिए उपलब्ध होता है।" फ्लोटिंग-पॉइंट नंबर "उपयोगी सन्निकटन" हैं। यदि आप कोड को एक फ़्लोटिंग-पॉइंट नंबर को दो दशमलव स्थानों पर राउंड करने के लिए कहते हैं, तो एक और फ़्लोटिंग-पॉइंट नंबर लौटाते हैं, इस बात की कोई गारंटी नहीं है कि "दाईं" उत्तर के निकटतम सन्निकटन में दशमलव के दाईं ओर केवल दो अंक होंगे। न्यूमेरिक्स प्रभावी रूप से पूर्णांक स्केल किए जाते हैं; उन्हें वह समस्या नहीं है।
माइक शेरिल 'कैट रिकॉल'

@Catcall अच्छा बिंदु - एक doubleसंस्करण roundको वापस करने की आवश्यकता होगी numericया (यूएचजी) text, इसलिए यह एक numericतर्क भी ले सकता है।
क्रेग रिंगर

6
@Catcall द्वारा टिप्पणी खोजने की कोशिश करने वालों के लिए: अब यह माइक शेरिल 'कैट रिकॉल' है
18446744073709551615

88

कास्टिंग के लिए पुराने सिंटैक्स को भी आज़माएं,

SELECT ROUND(AVG(some_column)::numeric,2)    
FROM table;

PostgreSQL के किसी भी संस्करण के साथ काम करता है।

भार के की कमी कर रहे हैं कुछ PostgreSQL कार्यों में, क्यों (???): मुझे लगता है कि "यह कमी है", लेकिन @CraigRinger, @Catcall और PostgreSQL टीम के बारे में "स्नातकोत्तर के ऐतिहासिक औचित्य" इस बात से सहमत (!)।

पुनश्च: गोलाई के बारे में एक और बिंदु सटीकता है , @ IanKenney का उत्तर जांचें


कास्टिंग रणनीति के रूप में ओवरलोडिंग

आप के साथ ROUND फ़ंक्शन को अधिभारित कर सकते हैं ,

 CREATE FUNCTION ROUND(float,int) RETURNS NUMERIC AS $$
    SELECT ROUND($1::numeric,$2);
 $$ language SQL IMMUTABLE;

अब आपका निर्देश ठीक काम करेगा, कोशिश करें (फ़ंक्शन निर्माण के बाद)

 SELECT round(1/3.,4); -- 0.3333 numeric

लेकिन यह एक NUMERIC प्रकार लौटाता है ... पहले कमोम-उपयोग अधिभार को संरक्षित करने के लिए, हम एक FLOAT प्रकार वापस कर सकते हैं जब एक पाठ पैरामीटर की पेशकश की जाती है,

 CREATE FUNCTION ROUND(float, text, int DEFAULT 0) 
 RETURNS FLOAT AS $$
    SELECT CASE WHEN $2='dec'
                THEN ROUND($1::numeric,$3)::float
                -- ... WHEN $2='hex' THEN ... WHEN $2='bin' THEN... complete!
                ELSE 'NaN'::float  -- like an error message 
            END;
 $$ 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'::text); -- need to cast string? pg bug 

पुनश्च: \df roundओवरलोडिंग के बाद जाँच , कुछ ऐसा दिखाएगा,

स्कीमा | नाम | परिणाम प्रकार | तर्क डेटा प्रकार
------------ + ------- + ------------------ + ---------- ------------------
 myschema | गोल | दोहरी सटीकता | डबल सटीक, पाठ, int
 myschema | गोल | सांख्यिक | डबल सटीक, int
 pg_catalog | गोल | दोहरी सटीकता | दोहरी सुनिश्चितता            
 pg_catalog | गोल | सांख्यिक | संख्यात्मक   
 pg_catalog | गोल | सांख्यिक | संख्यात्मक, int          

pg_catalogकार्यों डिफ़ॉल्ट होते हैं, को देखने के निर्माण में गणित कार्यों का मार्गदर्शन


38

इसके साथ प्रयास करें:

SELECT to_char (2/3::float, 'FM999999990.00');
-- RESULT: 0.67

या केवल:

SELECT round (2/3::DECIMAL, 2)::TEXT
-- RESULT: 0.67

5
मुझे यह इस सवाल का जवाब देने के लिए मेरे दिन के उत्तर के साथ बहुत अधिक संक्षिप्त और स्ट्रेट फॉरवर्ड कदम है। : धनुष:
सन

2
मुझे भी! बहुत ही छोटा और उपयोगी उपाय।
एलेक्सी शबरामोव

7

आप नीचे दिए गए फ़ंक्शन का उपयोग कर सकते हैं

 SELECT TRUNC(14.568,2);

परिणाम दिखाएगा:

14.56

आप अपने चर को इच्छा प्रकार में भी डाल सकते हैं:

 SELECT TRUNC(YOUR_VAR::numeric,2)

3

ब्रायन की प्रतिक्रिया के अनुसार आप एक क्वेरी में दशमलव को सीमित करने के लिए ऐसा कर सकते हैं। मैं किमी / घंटा से एम / एस में परिवर्तित करता हूं और इसे डाइग्राफ में प्रदर्शित करता हूं, लेकिन जब मैंने इसे डाइग्राफ में किया तो यह अजीब लग रहा था। इसके बजाय क्वेरी में गणना करते समय ठीक दिखता है। यह पोस्टग्रैस्कल 9.5.1 पर है।

select date,(wind_speed/3.6)::numeric(7,1) from readings;


1

त्रुटि: फ़ंक्शन राउंड (डबल सटीक, पूर्णांक) मौजूद नहीं है

समाधान : आपको कलाकारों को जोड़ना होगा तब यह काम करेगा

उदाहरण के लिए: round(extract(second from job_end_time_t)::integer,0)


0

कुल लेनदेन के रूप में ROUND (SUM (राशि) :: संख्यात्मक, 2) का चयन करें

देता है: २००२३४.०.08

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.