рдХрднреА-рдХрднреА, рдбреЗрдЯрд╛ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╕рдордп,
рд╕рдорд╕реНрдпрд╛ рдПрдХ рдирдореВрдиреЗ рдореЗрдВ "рдЪреЗрди" рдХреЛ
рднреЗрдж рдХрд░рдиреЗ рдХреА рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИ - рдЕрд░реНрдерд╛рддреН, рд░рд┐рдХреЙрд░реНрдб рдХреЗ
рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдЖрджреЗрд╢ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП
рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕реНрдерд┐рддрд┐ рдкреВрд░реА рд╣реЛрддреА рд╣реИ ред
рдпрд╣ рдпрд╛ рддреЛ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдбреЗрдЯрд╛ рдкрд░ рдПрдХ рд╕реНрдерд┐рддрд┐ рд╣реЛ рд╕рдХрддреА рд╣реИ, рдпрд╛ рдПрдХ рдпрд╛ рдПрдХ рд╕реЗ рдЕрдзрд┐рдХ рдкрд┐рдЫрд▓реЗ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рдВрдмрдВрдз рдореЗрдВ рдПрдХ рдЬрдЯрд┐рд▓ рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд░реАрдмреА рд╕рдордп рдХреЗ рдирдореВрдиреЛрдВ рдХреЗ рдмреАрдЪ рдЕрдВрддрд░рд╛рд▓ рдХреА рд▓рдВрдмрд╛рдИред

рдкрд╛рд░рдВрдкрд░рд┐рдХ рд╕рдорд╛рдзрд╛рди "рд╕реНрд╡рдпрдВ рдЬреБрдбрд╝рдиреЗ" рдХреЗ рд▓рд┐рдП рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╡рд┐рдХрд▓реНрдк рдкреНрд░рджрд╛рди рдХрд░рддреЗ рд╣реИрдВ, рдЬрдм рдирдореВрдирд╛ рдЦреБрдж рд╕реЗ рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдпрд╛ рдХреБрдЫ рддрдереНрдпреЛрдВ "рдбреЗрдЯрд╛ рдХреЗ рдмрд╛рд╣рд░" рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ - рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд░рд┐рдХреЙрд░реНрдб рдореЗрдВ рдПрдХ рд╕рдЦреНрддреА рд╕реЗ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрджрдо (рдПрди + 1, "рд╣рд░ рджрд┐рди" рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдП ...) )ред
рдкрд╣рд▓рд╛ рд╡рд┐рдХрд▓реНрдк рдЕрдХреНрд╕рд░ рд░рд┐рдХреЙрд░реНрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рдВрджрд░реНрдн рдореЗрдВ рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреЗ
рджреНрд╡рд┐рдШрд╛рдд рдЬрдЯрд┐рд▓рддрд╛ рдХреА рдУрд░ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ
рдмрдбрд╝реЗ рдирдореВрдиреЛрдВ рдореЗрдВ рдЕрд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИ , рдФрд░ рджреВрд╕рд░рд╛
рдЖрд╕рд╛рдиреА рд╕реЗ "рдЧрд┐рд░" рд╕рдХрддрд╛ рд╣реИ рдпрджрд┐ рд╕реНрд░реЛрдд рдбреЗрдЯрд╛ рдореЗрдВ рдЕрдЪрд╛рдирдХ рдХреЛрдИ рдирдореВрдирд╛ рдирд╣реАрдВ рд╣реИред
рд▓реЗрдХрд┐рди рдпрд╣ рдХрд╛рд░реНрдп рд╣рдореЗрдВ PostgreSQL рдореЗрдВ
рд╡рд┐рдВрдбреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рдкреНрд░рднрд╛рд╡реА рдврдВрдЧ рд╕реЗ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред
рдХрд╛рд░реНрдп: рдЕрдиреНрдп рд▓реЛрдЧреЛрдВ рдХреЗ рдкреИрд╕реЗ рдЧрд┐рдирдирд╛
рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рд╕рдмрд╕реЗ рд╕рд░рд▓ рдорд╛рдорд▓реЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ - рдЬрдм рдирд┐рд░рдВрддрд░рддрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рдбреЗрдЯрд╛ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИред
рдЖрдЧреЗ рдХреЗ рд╕рднреА рдСрдкрд░реЗрд╢рди рдЕрд▓рдЧ рд╕реЗ рдирд╣реАрдВ рдХрд░рдиреЗ рд╣реЛрдВрдЧреЗред рд▓реЗрдХрд┐рди рдПрд▓реНрдЧреЛрд░рд┐рдереНрдо рдХреА рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдЗрд╕реЗ рдХреНрд░рдорд┐рдХ рдЪрд░рдгреЛрдВ рдореЗрдВ рддреЛрдбрд╝ рджреВрдВрдЧрд╛, рдФрд░
рдЕрдВрдд рдореЗрдВ рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рдФрд░ рдХреИрд╕реЗ рдЕрдиреБрдХреВрд▓рди рдХрд░рдирд╛ рд╣реИ ред
рдЖрдЗрдП рдХрд▓реНрдкрдирд╛ рдХрд░реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдЫреЛрдЯрд╛ рдмреИрдВрдХ рд╣реИ рдЬреЛ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдЧреНрд░рд╛рд╣рдХ рдЦрд╛рддреЛрдВ рдкрд░ рд╕рдВрддреБрд▓рди рдмрдирд╛рдП рд░рдЦрддрд╛ рд╣реИред рдЬреИрд╕реЗ рд╣реА рд░рд╕реАрдж рдФрд░ рд╡реНрдпрдп рдХрд╛ рд▓реЗрдирджреЗрди рд╣реЛрддрд╛ рд╣реИ, рдпрд╣ рддрд┐рдерд┐ рджрд┐рди рдХреЗ рдЕрдВрдд рдореЗрдВ рдХреБрд▓ рдмрд┐рд▓ рд░рд╛рд╢рд┐ рдХреЛ рднреА рдареАрдХ рдХрд░ рджреЗрддреА рд╣реИред
рдирдП рд╕рд╛рд▓ рдХреА рд▓рдВрдмреА рдЫреБрдЯреНрдЯреА рдХреЗ рдмрд╛рдж, рдмреИрдВрдХ рдиреЗ рдЕрдкрдиреЗ рдЧреНрд░рд╛рд╣рдХреЛрдВ рдХреЛ рдкреБрд░рд╕реНрдХреГрдд рдХрд░рдиреЗ рдХрд╛ рдлреИрд╕рд▓рд╛ рдХрд┐рдпрд╛ - рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рд╡реНрдпрдХреНрддрд┐ рдЬрд┐рд╕рдиреЗ рдЗрд╕ рд╡рд░реНрд╖ рдПрдХ рдЦрд╛рддрд╛ рдЦреЛрд▓рд╛ рд╣реИ, рдЬрдм рд╡рд╣ рдЦрд╛рддрд╛ "рд░реАрд╕реЗрдЯ" рдирд╣реАрдВ рдерд╛ рддрдм рд╕рдмрд╕реЗ рд▓рдВрдмреЗ рд╕рдордп рддрдХ рдирд┐рд░рдВрддрд░ рджреИрдирд┐рдХ рдмреИрд▓реЗрдВрд╕ рдХрд╛ 1% рдЕрд░реНрдЬрд┐рдд рдХрд┐рдпрд╛ред
рдпрд╣рд╛рдБ рдпрд╣ "рд╢реНрд░реГрдВрдЦрд▓рд╛" рдХреА рдирд┐рд░рдВрддрд░рддрд╛ рдХреЗ рд▓рд┐рдП рд╣рдорд╛рд░реА рдХрд╕реМрдЯреА рд╣реИред рдЦреИрд░, рдбреЗрдЯрд╛ рдХрд╛ рдХреНрд░рдо рд╢реЗрд╖ рд░рд╛рд╢рд┐ рдХреА рддрд╛рд░реАрдЦреЛрдВ рд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╣реЛрдЧрд╛ред
рд╡реЗ рд╣рдореЗрдВ рдРрд╕реЗ рд╕реАрдПрд╕рд╡реА рд▓рд╛рдП, рдФрд░ рдЬрд▓реНрджреА рд╕реЗ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рд╛ рдХрд┐ рдмреИрдВрдХ рд╕реЗ рдЗрддрдиреА рдЙрджрд╛рд░рддрд╛ рдХрд┐рд╕реЗ рдФрд░ рдХрд┐рддрдиреА рдорд┐рд▓рдиреА рдЪрд╛рд╣рд┐рдП:
date;client;balance 01.01.2020;;150 01.01.2020;;100 02.01.2020;;100 02.01.2020;;150 03.01.2020;;200 05.01.2020;;0 06.01.2020;;50 08.01.2020;;0 08.01.2020;;200 09.01.2020;;0 09.01.2020;;0 10.01.2020;;5
рдЗрд╕ рдбреЗрдЯрд╛ рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдпреЛрдЧреНрдп рдХреБрдЫ рддрдереНрдпреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ:
- 01.01 рдПрдХ рдЫреБрдЯреНрдЯреА рдереА, рдФрд░ рдмреИрдВрдХ рдиреЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛ред рдЗрд╕рд▓рд┐рдП, рдХрд┐рд╕реА рднреА рдЧреНрд░рд╛рд╣рдХ рдХреЗ рдкрд╛рд╕ рдЙрд╕ рджрд┐рди рд╢реЗрд╖ рд░рд╛рд╢рд┐ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд░рд┐рдХреЙрд░реНрдб рдирд╣реАрдВ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЙрдирдХреЗ рдЦрд╛рддреЛрдВ рдореЗрдВ рдкреИрд╕рд╛ рд╣реИред рдпрд╣реА рд╣реИ, "рдЬрд╛рдирд╡рд░ рдмрд▓" рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдХрд┐ рджрд┐рди рдХреЗ рджреНрд╡рд╛рд░рд╛ рдкреБрдирд░рд╛рд╡реГрддрд┐ рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдХрд╛рдо рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ред
- 04.01 рдПрд▓рд┐рд╕ рдиреЗ рдХреЛрдИ рдСрдкрд░реЗрд╢рди рдирд╣реАрдВ рдХрд┐рдпрд╛, рдЗрд╕рд▓рд┐рдП рдХреЛрдИ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдирд╣реАрдВ рд╣реИред рд▓реЗрдХрд┐рди 05.01 рд╕реЗ рдкрд╣рд▓реЗ, рдЙрд╕рдХреЗ рдЦрд╛рддреЗ рдХреА рд░рд╛рд╢рд┐ рдЧреИрд░-рд╢реВрдиреНрдп рдереА - рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдореЗрдВ рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
- рд╣рдо 01.01-12.01 рдХреЛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЗрд╕ рдЕрд╡рдзрд┐ рдХреЗ рдЕрдВрдд рдореЗрдВ рдРрд▓рд┐рд╕ рдХрд╛ рдЦрд╛рддрд╛ рд╢реЗрд╖ рдЧреИрд░-рд╢реВрдиреНрдп рд╣реИред рд╣рдо рдЕрд╡рдзрд┐ рдХреЛ рд╕реАрдорд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЛ рднреА рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВред
рд╕реАрдПрд╕рд╡реА рдХрд░рдиреЗ рд╡рд╛рд▓реА рддрд╛рд▓рд┐рдХрд╛
CSV рд╕реЗ рдЖрдпрд╛рдд рдХрд░рдиреЗ рдХрд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рддрд░реАрдХрд╛
COPY рдСрдкрд░реЗрдЯрд░ рд╣реИ ред рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕реЗ рдЧрд░реНрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдирд┐рдпрдорд┐рдд рдЕрднрд┐рд╡реНрдпрдХреНрддрд┐ рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдХрд░рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реЗрдВрдЧреЗ:
CREATE TEMPORARY TABLE tbl AS SELECT to_date(prt[1], 'DD.MM.YYYY') dt , prt[2] client , prt[3]::numeric(32,2) balance FROM ( SELECT regexp_split_to_array(str, ';') prt FROM ( SELECT regexp_split_to_table( $$ date;client;balance 01.01.2020;;150 01.01.2020;;100 02.01.2020;;100 02.01.2020;;150 03.01.2020;;200 05.01.2020;;0 06.01.2020;;50 08.01.2020;;0 08.01.2020;;200 09.01.2020;;0 09.01.2020;;0 10.01.2020;;5 $$ , E'\\n') str ) T WHERE str <> '' OFFSET 1 ) T;
рдпрд╣ рдЗрд╕ рдЕрд░реНрде рдореЗрдВ рдПрдХ "рдмреЗрдИрдорд╛рди" рддрд░реАрдХрд╛ рд╣реИ рдХрд┐ рдпрд╣ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдирд╣реАрдВ рдкрдЪрддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд╢рд░реАрд░ рдореЗрдВ рдПрдХ рд╡рд┐рднрд╛рдЬрдХ рдкрд░рд┐рд░рдХреНрд╖рдгред рд▓реЗрдХрд┐рди рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рд░рд▓ рдЕрдиреБрдкреНрд░рдпреЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП - рдЙрдкрдпреБрдХреНрддред
рдЪрд░рдг 1: рдЖрд╡реЗрджрди рдХреА рд╕реНрдерд┐рддрд┐ рдареАрдХ рдХрд░реЗрдВ
рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╢реНрд░реГрдВрдЦрд▓рд╛ рдирд┐рд░рдВрддрд░рддрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдПрдХ рдиреЙрдирдЬрд░реЛ рдмреИрд▓реЗрдВрд╕ рд╣реИред рд╣рдо рдЗрд╕реЗ рдПрдХ рдЕрд▓рдЧ рдХреНрд╖реЗрддреНрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд╕реНрдкрд╖реНрдЯрддрд╛ рдХреЗ рд▓рд┐рдП, рдХреНрд▓рд╛рдЗрдВрдЯ рджреНрд╡рд╛рд░рд╛ рдХрд╛рд▓рд╛рдиреБрдХреНрд░рдорд┐рдХ рдХреНрд░рдо рд╕реЗ:
SELECT * , balance > 0 cond FROM tbl ORDER BY client, dt;
dt | client | balance | cond ------------------------------------ 2020-01-01 | | 150.00 | t 2020-01-02 | | 100.00 | t 2020-01-03 | | 200.00 | t 2020-01-05 | | 0.00 | f 2020-01-06 | | 50.00 | t 2020-01-08 | | 0.00 | f 2020-01-09 | | 0.00 | f 2020-01-10 | | 5.00 | t 2020-01-01 | | 100.00 | t 2020-01-02 | | 150.00 | t 2020-01-08 | | 200.00 | t 2020-01-09 | | 0.00 | f
рдЪрд░рдг 2: рд▓рд╛рдкрддрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ
рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдмреЙрдм рдХреА рд░рд╛рд╢рд┐ 02.01 рд╕реЗ 08.01 рддрдХ рдирд╣реАрдВ рдмрджрд▓реАред рдФрд░ рд╕рдорд╕реНрдпрд╛ рдХреА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рд╣рдореЗрдВ
рдФрд╕рдд рджреИрдирд┐рдХ рд╢реЗрд╖ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдП - рдЕрд░реНрдерд╛рдд, рд╣рдореЗрдВ рдЗрди "рдЫреВрдЯреЗ рд╣реБрдП рджрд┐рдиреЛрдВ" рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдЪрд╛рд╣рд┐рдПред рдпрд╛ рдХрдо рд╕реЗ рдХрдо рджрд┐рдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЬрдм рдореВрд▓реНрдп рд╕рдорд╛рди рд░рд╣реЗ:
coalesce(lead(dt) OVER(PARTITION BY client ORDER BY dt), '2020-01-12') - dt days
dt | client | balance | cond | days ------------------------------------------- 2020-01-01 | | 150.00 | t | 1 2020-01-02 | | 100.00 | t | 1 2020-01-03 | | 200.00 | t | 2 2020-01-05 | | 0.00 | f | 1 2020-01-06 | | 50.00 | t | 2 2020-01-08 | | 0.00 | f | 1 2020-01-09 | | 0.00 | f | 1 2020-01-10 | | 5.00 | t | 2 2020-01-01 | | 100.00 | t | 1 2020-01-02 | | 150.00 | t | 6 2020-01-08 | | 200.00 | t | 1 2020-01-09 | | 0.00 | f | 3
рд▓реАрдб () рд╡рд┐рдВрдбреЛ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ
рд╣реБрдП, рд╣рдордиреЗ рдЖрджреЗрд╢ рдореЗрдВ
рдЕрдЧрд▓реЗ рд░рд┐рдХреЙрд░реНрдб рд╕реЗ рддрд╛рд░реАрдЦ рд╕реАрдЦреА, рдФрд░
рдореЛрдЯреЗ рддреМрд░ рдкрд░ рд╣рдордиреЗ рдкрд┐рдЫрд▓реЗ рдПрдХ рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдХреЛ рд╕реАрдорд┐рдд рдХрд░ рджрд┐рдпрд╛ред рдЗрд╕реА рд╕рдордп, рдЙрдиреНрд╣реЛрдВрдиреЗ рдЙрдкрдпреЛрдЧреА рд╕рдВрдкрддреНрддрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдХрд┐
PostgreSQL рдореЗрдВ рджреЛ рддрд┐рдерд┐рдпреЛрдВ рдХрд╛
рдЕрдВрддрд░ рдЙрди рджреЛрдиреЛрдВ рдХреЗ рдмреАрдЪ
рдПрдХ рдкреВрд░реНрдгрд╛рдВрдХ рд╕рдВрдЦреНрдпрд╛ рджреЗрддрд╛ рд╣реИред
рд▓рдЧрднрдЧ рдореБрдлреНрдд рдмреЛрдирд╕ рдХреЗ рд░реВрдк рдореЗрдВ, рд╣рдореЗрдВ рд╢реВрдиреНрдп рдмреИрд▓реЗрдВрд╕ рд╡рд╛рд▓реЗ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП рд╕рднреА рд╕рдорд╛рди рдЬрд╛рдирдХрд╛рд░реА рдорд┐рд▓реАред рд▓реЗрдХрд┐рди рдЕрдЧрд░ рдХреЛрдИ рдЧреИрд░-рдкреВрд░реНрдг рд╢рд░реНрдд рд╡рд╛рд▓реА рдмрд╣реБрдд рд╕реА рд▓рд╛рдЗрдиреЗрдВ рд╣реИрдВ рдЬреЛ рд╣рдореЗрдВ рд░реБрдЪрд┐ рдирд╣реАрдВ рджреЗрддреА рд╣реИрдВ, рддреЛ рд╕рд░реНрд╡рд░ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХреЛ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП
CASE рдХреЗ рддрд╣рдд рдРрд╕реА
рдЧрдгрдирд╛рдУрдВ рдХреЛ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдордЭ рдореЗрдВ рдЖрддрд╛
рд╣реИ ред
рдЪрд░рдг 3: рдмреНрд░реЗрдХ рдкреЙрдЗрдВрдЯ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ
рдкреНрд░рддреНрдпреЗрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╣рдо рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ, рд╡рд╣ рдмрд┐рдВрджреБ рд╣реИ рдЬрд╣рд╛рдВ рдкрд╣рд▓реЗ рдХреА рдЧрдгрдирд╛ рдХреА рдЧрдИ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдореВрд▓реНрдп
рдкрд┐рдЫрд▓реЗ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд╕рд╛рдкреЗрдХреНрд╖ рдмрджрд▓рддрд╛ рд╣реИред рд╣рдо рдРрд╕реЗ рдмрд┐рдВрджреБрдУрдВ рдХреЛ рдЦреЛрдЬрдиреЗ рдХреЗ рд▓рд┐рдП
рдЕрдВрддрд░рд╛рд▓ () рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ:
lag(cond) OVER(PARTITION BY client ORDER BY dt) IS DISTINCT FROM cond chain_start
dt | client | balance | cond | days | chain_start --------------------------------------------------------- 2020-01-01 | | 150.00 | t | 1 | t 2020-01-02 | | 100.00 | t | 1 | f 2020-01-03 | | 200.00 | t | 2 | f 2020-01-05 | | 0.00 | f | 1 | t 2020-01-06 | | 50.00 | t | 2 | t 2020-01-08 | | 0.00 | f | 1 | t 2020-01-09 | | 0.00 | f | 1 | f 2020-01-10 | | 5.00 | t | 2 | t 2020-01-01 | | 100.00 | t | 1 | t 2020-01-02 | | 150.00 | t | 6 | f 2020-01-08 | | 200.00 | t | 1 | f 2020-01-09 | | 0.00 | f | 3 | t
<> рдХреЗ рдмрдЬрд╛рдп
IS DISTINCT FROM рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдордиреЗ рдкреНрд░рддреНрдпреЗрдХ рдХреНрд▓рд╛рдЗрдВрдЯ рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП NULL рдХреЗ рд╕рд╛рде рддреБрд▓рдирд╛ рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛рдУрдВ рд╕реЗ рдмрдЪрд╛ рд▓рд┐рдпрд╛ред рддрджрдиреБрд╕рд╛рд░, рд╕рднреА рд▓рд╛рдЗрдиреЗрдВ рдЬрд╣рд╛рдВ рдореВрд▓реНрдп TRUE рдПрдХ рдирдИ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреА рд╢реБрд░реБрдЖрдд рд╣реИ, рдФрд░ FALSE рдЗрд╕рдХреА рдирд┐рд░рдВрддрд░рддрд╛ рд╣реИред
рдЪрд░рдг 4: рд▓рд┐рдВрдХ рдХреЛ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХрд░реЗрдВ
рдкреНрд░рддреНрдпреЗрдХ рд╡реНрдпрдХреНрддрд┐рдЧрдд рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреЗ рднреАрддрд░ рдбреЗрдЯрд╛ рдХреЛ рд╕рдореВрд╣реАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП
, рдЕрдкрдиреЗ рд╕рднреА рд░рд┐рдХреЙрд░реНрдб рдХреЗ рд▓рд┐рдП
рд╕рдорд╛рди рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХреЛ рдЕрд╕рд╛рдЗрди
рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЖрд╕рд╛рди рд╣реИред рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреА рдХреНрд░рдо рд╕рдВрдЦреНрдпрд╛ рд╣реА рдЗрд╕рдХреЗ рд▓рд┐рдП рдПрдХрджрдо рд╕рд╣реА рд╣реИред рдФрд░ рдпрд╣
рд╢реНрд░реГрдВрдЦрд▓рд╛ рдХреА "рд╢реБрд░реБрдЖрдд" рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ рдЬреЛ рдирдореВрдиреЗ рдореЗрдВ рдЕрдзрд┐рдХ рдкрд╛рдП рдЧрдП рдереЗред
рдЙрдиреНрд╣реЗрдВ рдпрд╛ рддреЛ рдЧрдгрдирд╛ рдХреА рдЬрд╛ рд╕рдХрддреА рд╣реИ "рд╡рд┐рдВрдбреЛ" рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдмреВрд▓ рдорд╛рди рдпреЛрдЧ рдХрд╛ рдпреЛрдЧ ({рдмреВрд▓рд┐рдпрди} :: рдкреВрд░реНрдгрд╛рдВрдХ), рдпрд╛ рдЧрд┐рдирддреА рд╕реЗ рдореЗрд▓ рдЦрд╛рдиреЗ рд╡рд╛рд▓реЗ рд░рд┐рдХреЙрд░реНрдб рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рдХреЗ (*) рдлрд╝рд┐рд▓реНрдЯрд░ ({рдмреБрд▓рд┐рдпрди}) рдХреА рд╕реНрдерд┐рддрд┐ред рд╣рдо рджреВрд╕рд░реЗ рд╡рд┐рдХрд▓реНрдк рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗ:
count(*) FILTER(WHERE chain_start) OVER(PARTITION BY client ORDER BY dt) grpid
dt | client | balance | cond | days | chain_start | grpid ----------------------------------------------------------------- 2020-01-01 | | 150.00 | t | 1 | t | 1 2020-01-02 | | 100.00 | t | 1 | f | 1 2020-01-03 | | 200.00 | t | 2 | f | 1 2020-01-06 | | 50.00 | t | 2 | t | 2 2020-01-10 | | 5.00 | t | 2 | t | 3 2020-01-01 | | 100.00 | t | 1 | t | 1 2020-01-02 | | 150.00 | t | 6 | f | 1 2020-01-08 | | 200.00 | t | 1 | f | 1
рдЗрд╕ рдЪрд░рдг рдореЗрдВ, рд╣рдо рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреНрд░рддреНрдпреЗрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рд╕рднреА рд▓рд┐рдВрдХ рдХреА рд▓рдВрдмрд╛рдИ рдЬрд╛рдирддреЗ рд╣реИрдВ, рд╣рдореЗрдВ рдЕрдм "рдирд┐рд░реНрдмрд╛рдз" рд░рд┐рдХреЙрд░реНрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдмрд╕ рдЙрдиреНрд╣реЗрдВ рдлрд╝рд┐рд▓реНрдЯрд░ рдХрд░реЗрдВред
рдЪрд░рдг 5: рдЬрдВрдЬреАрд░реЛрдВ рдХреЛ рд▓рдЧрд╛рдирд╛
рдПрдХ рд╢реНрд░реГрдВрдЦрд▓рд╛ рдореЗрдВ рд╕рднреА рджрд┐рдиреЛрдВ рдХреЗ рдФрд╕рдд рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдХреБрд▓ рджрд┐рдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдФрд░ "рдЕрднрд┐рдиреНрди" рд╕рдВрддреБрд▓рди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
SELECT client , min(dt) chain_dt , sum(days * balance) balance , sum(days) days FROM ... GROUP BY 1, grpid ORDER BY 1, grpid;
client | chain_dt | balance | days ------------------------------------- | 2020-01-01 | 650.00 | 4 | 2020-01-06 | 100.00 | 2 | 2020-01-10 | 10.00 | 2 | 2020-01-01 | 1200.00 | 8
рдЪрд░рдг 6: рдПрдкреНрд▓рд╛рдЗрдб рд╣рд╛рдИ рдХреА рддрд▓рд╛рд╢ рдореЗрдВ
DISTINCT ON рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ
, рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдЧреНрд░рд╛рд╣рдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдПрдХрд▓ рд░рд┐рдХреЙрд░реНрдб (рдЕрдзрд┐рдХрддрдо рджрд┐рдиреЛрдВ рдХреЗ рд╕рд╛рде) рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗ:
SELECT DISTINCT ON(client) * FROM ... ORDER BY client, days DESC;
client | chain_dt | balance | days ------------------------------------- | 2020-01-01 | 650.00 | 4 | 2020-01-01 | 1200.00 | 8
рджрд░рдЕрд╕рд▓, рдпрд╣ рд╕рдм, рд╡рд╣ рд╕рдм рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рд╣реИ ...
рд╣рдо рдЧрдардмрдВрдзрди рдФрд░ рдЕрдиреБрдХреВрд▓рди рдХрд░рддреЗ рд╣реИрдВ
рд╕рд╛рд░рд╛рдВрд╢ рдЕрдиреБрд░реЛрдз WITH step123 AS ( SELECT * , CASE WHEN cond THEN lag(cond) OVER(w) IS DISTINCT FROM cond END chain_start , CASE WHEN cond THEN coalesce(lead(dt) OVER(w), '2020-01-12') - dt END days FROM tbl , LATERAL(SELECT balance > 0 cond) T WINDOW w AS (PARTITION BY client ORDER BY dt) ) , step4 AS ( SELECT * , count(*) FILTER(WHERE chain_start) OVER(PARTITION BY client ORDER BY dt) grpid FROM step123 WHERE cond ) SELECT DISTINCT ON(client) client , sum(days) OVER(w) days , min(dt) OVER(w) chain_dt , sum(days * balance) OVER(w) balance FROM step4 WINDOW w AS (PARTITION BY client, grpid) ORDER BY 1, 2 DESC;
рдпрд╣рд╛рдВ рд╣рдордиреЗ рдкрд╣рд▓реЗ рддреАрди рдЪрд░рдгреЛрдВ рдХреЛ рд╕рдВрдпреБрдХреНрдд рдФрд░ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рд╣реИ:
- LATERAL рдЙрдкрд╢реНрд░реЗрдгреА рдиреЗ рд╣рдореЗрдВ рдЪрдпрди рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдкрд╛рд╕ рдХреЗ рдмрд┐рдирд╛ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рдХреНрд╖реЗрддреНрд░ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдФрд░ рддреБрд░рдВрдд рдлрд╝рдВрдХреНрд╢рди рдореЗрдВ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреА
- WINDOW рдХреЗ рддрд╣рдд рдПрдХ рд╕рд╛рдорд╛рдиреНрдп рдкрд░рд┐рднрд╛рд╖рд╛ рдХреЛ рд╣рдЯрд╛рдиреЗ рд╕реЗ PostgreSQL рдХреЛ "рд╡рд┐рдВрдбреЛ" рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдбрдмрд▓ рд╕реЙрд░реНрдЯрд┐рдВрдЧ рдирд╣реАрдВ рдХрд░рдиреЗ рдореЗрдВ рдорджрдж рдорд┐рд▓рддреА рд╣реИ рдФрд░ рджреЛрдиреЛрдВ рдХрд╛рд░реНрдп рдПрдХ WindowAgg рдиреЛрдб рдореЗрдВ рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ
- CASE рдХреЗ рддрд╣рдд "рдЖрд▓рд╕реА" рдлрд╝рдВрдХреНрд╢рди рдХреА рдЧрдгрдирд╛ рдкреНрд░рджрд░реНрд╢рди рдХрд┐рдП рдЧрдП рдХрд╛рд░реНрдпреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдХрдо рдХрд░рддреА рд╣реИ
рдЗрд╕реА рддрд░рд╣, рд╣рдордиреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рджреЛ рдЪрд░рдгреЛрдВ рдХреЛ рд╕рдВрдпреБрдХреНрдд рдХрд┐рдпрд╛ред рд▓реЗрдХрд┐рди рд╕рдореБрдЪреНрдЪрдп (рдХреНрд▓рд╛рдЗрдВрдЯ, рдЧреНрд░рд┐рдб) рдФрд░ рдпреВрдиреАрдХрд▓рд╛рдЗрдЬрд╝реЗрд╢рди (рдХреНрд▓рд╛рдЗрдВрдЯ, рдпреЛрдЧ (рджрд┐рди)) рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП "рд╡рд┐рдВрдбреЛ" рдХрд╛ рдХреНрд░рдо рд╕рдВрдпреЛрдЧ рдирд╣реАрдВ рдерд╛, рдЗрд╕рд▓рд┐рдП рд╡рд┐рдВрдбреЛ рдмреНрд▓реЙрдХ рд╕реЗ рдкрд╣рд▓реЗ рдФрд░ рдпреВрдирд┐рдХ рд╕реЗ рдкрд╣рд▓реЗ - рдЕрднреА рднреА рдЖрдЦрд┐рд░реА рдмреНрд▓реЙрдХ рдореЗрдВ рджреЛ рд╕реЙрд░реНрдЯ рдиреЛрдб рд╣реЛрдВрдЧреЗред
[рд╕реНрдкрд╖реНрдЯреАрдХрд░рдг рдкрд░ рджреЗрдЦреЗрдВ редensor.ru]рдореИрдВ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реВрдВ рдХрд┐ рдЬрдм рдЪреЗрди рдХреА рд╕рдВрдЦреНрдпрд╛ рд╣реЛрддреА рд╣реИ
, рддреЛ WHERE рдХреА рд╕реНрдерд┐рддрд┐ рдкрд╣рд▓реЗ рдкреВрд░реА рд╣реЛ рдЬрд╛рддреА рд╣реИ , рдЗрд╕рд▓рд┐рдП
рд╡рд┐рдВрдбреЛ рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рд╕рдВрдЦреНрдпрд╛рдПрдВ рдЕрдиреБрдХреНрд░рдорд┐рдХ рд╣реЛ рдЬрд╛рддреА рд╣реИрдВред