PostgreSQL
 sql >> डेटाबेस >  >> RDS >> PostgreSQL

pgSql के साथ समान कॉलम की पिछली पंक्ति को कैसे क्वेरी करें

उपयोगकर्ता-निर्धारित समुच्चय का उपयोग करें

लाइव परीक्षण:http://sqlfiddle.com/#!17/03ee7/1

डीडीएल

CREATE TABLE t
    (grop varchar(1), month_year text, something int)
;

INSERT INTO t
    (grop, month_year, something)
VALUES
    ('a', '201901', -2),
    ('a', '201902', -4),
    ('a', '201903', -6),
    ('a', '201904', 60),
    ('a', '201905', -2),
    ('a', '201906', 9),
    ('a', '201907', 11),
    ('b', '201901', 100),
    ('b', '201902', -200),
    ('b', '201903', 300),
    ('b', '201904', -50),
    ('b', '201905', 30),
    ('b', '201906', -88),
    ('b', '201907', -86)
;

उपयोगकर्ता-निर्धारित समुच्चय

create or replace function negative_accum(_accumulated_b numeric, _current_b numeric)
returns numeric as
$$
    select case when _accumulated_b < 0 then
        _accumulated_b + _current_b
    else
        _current_b
    end
$$ language 'sql';

create aggregate negative_summer(numeric)
(
    sfunc = negative_accum,
    stype = numeric,
    initcond = 0
);

select  
    *, 
  negative_summer(something) over (order by grop, month_year) as result
from t

पहला पैरामीटर (_accumulated_b) कॉलम का संचित मान रखता है। दूसरा पैरामीटर (_current_b) वर्तमान पंक्ति के कॉलम का मान रखता है।

आउटपुट:

आपके छद्म कोड के लिए B3 = A3 + MIN(0, B2)

मैंने इस विशिष्ट कोड का उपयोग किया:

select case when _accumulated_b < 0 then
    _accumulated_b + _current_b
else
    _current_b
end

इसे पोस्टग्रेज में मुहावरेदार तरीके से लिखा जा सकता है:

select _current_b + least(_accumulated_b, 0)

लाइव परीक्षण:http://sqlfiddle.com/#!17/70fa8/1

create or replace function negative_accum(_accumulated_b numeric, _current_b numeric)
returns numeric as
$$
    select _current_b + least(_accumulated_b, 0) 
$$ language 'sql';

आप संचायक फ़ंक्शन के साथ अन्य भाषा का भी उपयोग कर सकते हैं, उदाहरण के लिए, plpgsql। ध्यान दें कि plpgsql (या शायद $$ उद्धरण) http://sqlfiddle.com में समर्थित नहीं है। . तो कोई लाइव टेस्ट लिंक नहीं, हालांकि यह आपकी मशीन पर काम करेगा:

create or replace function negative_accum(_accumulated_b numeric, _current_b numeric)
returns numeric as
$$begin
    return _current_b + least(_accumulated_b, 0);
end$$ language 'plpgsql';

अपडेट करें

मैं partition by से चूक गया , यहां एक उदाहरण डेटा है (11 से -11 में बदला गया) जहां बिना partition by . के और partition by . के साथ अलग परिणाम देगा:

लाइव परीक्षण:http://sqlfiddle.com/#!17/87795/4

INSERT INTO t
    (grop, month_year, something)
VALUES
    ('a', '201901', -2),
    ('a', '201902', -4),
    ('a', '201903', -6),
    ('a', '201904', 60),
    ('a', '201905', -2),
    ('a', '201906', 9),
    ('a', '201907', -11), -- changed this from 11 to -11
    ('b', '201901', 100),
    ('b', '201902', -200),
    ('b', '201903', 300),
    ('b', '201904', -50),
    ('b', '201905', 30),
    ('b', '201906', -88),
    ('b', '201907', -86)
;

आउटपुट:

| grop | month_year | something | result_wrong | result |
|------|------------|-----------|--------------|--------|
|    a |     201901 |        -2 |           -2 |     -2 |
|    a |     201902 |        -4 |           -6 |     -6 |
|    a |     201903 |        -6 |          -12 |    -12 |
|    a |     201904 |        60 |           48 |     48 |
|    a |     201905 |        -2 |           -2 |     -2 |
|    a |     201906 |         9 |            7 |      7 |
|    a |     201907 |       -11 |          -11 |    -11 |
|    b |     201901 |       100 |           89 |    100 |
|    b |     201902 |      -200 |         -200 |   -200 |
|    b |     201903 |       300 |          100 |    100 |
|    b |     201904 |       -50 |          -50 |    -50 |
|    b |     201905 |        30 |          -20 |    -20 |
|    b |     201906 |       -88 |         -108 |   -108 |
|    b |     201907 |       -86 |         -194 |   -194 |


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. मैं एसक्यूएल के साथ स्ट्रिंग में प्रत्येक अक्षर के लिए केस कैसे स्विच कर सकता हूं?

  2. किसी फ़ंक्शन से लौटाई गई तालिका से अलग-अलग कॉलम कैसे प्राप्त करें?

  3. openerp:ubuntu पर आंतरिक सर्वर त्रुटि

  4. प्राथमिक कुंजी के लिए यूयूआईडी या अनुक्रम?

  5. PostgreSQL बहु-स्तंभ आंशिक अनुक्रमणिका में डेटाटाइम बाधा जोड़ें