PostgreSQL рджрд┐рдирд╛рдВрдХ рдЕрдиреБрдХреНрд░рдо рдЬрдирд░реЗрд╢рди рдФрд░ Gener_series

рд╕рд╛рдЗрдХрд┐рд▓ рдХреА рдЪреЗрддрд╛рд╡рдиреА

рдпрд╣ рд▓реЗрдЦ рд╕рд╛рдЗрдХрд┐рд▓ рдирд┐рд░реНрдорд╛рдг рдХрд╛ рдПрдХ рдЧреЛрд▓рд╛рдХрд╛рд░ рдЙрджрд╛рд╣рд░рдг рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдпрджрд┐ рдЖрдк рд╕рдорд╕реНрдпрд╛ рдХрд╛ рдПрдХ рдорд╛рдирдХ рдпрд╛ рдЕрдзрд┐рдХ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рд╕рдорд╛рдзрд╛рди рдЬрд╛рдирддреЗ рд╣реИрдВ, рддреЛ рдореБрдЭреЗ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рджреЗрдЦрдХрд░ рдЦреБрд╢реА рд╣реЛрдЧреАред


рдПрдХ рдмрд╛рд░ рдкрд░рд┐рдпреЛрдЬрдирд╛рдУрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдкрд░ рд╣рдореЗрдВ рдорд╣реАрдиреЗ рдХреЗ рдЕрдВрдд рдореЗрдВ рд╕рдмрдЯреЛрдЯрд▓реНрд╕ рдХреЗ рд╕рдореВрд╣ рдХреЗ рд╕рд╛рде рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рд╡рд┐рддреНрддреАрдп рд▓реЗрдирджреЗрди рдкрд░ рдПрдХ рд░рд┐рдкреЛрд░реНрдЯ рддреИрдпрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдереАред


рдХрд╛рд░реНрдп рдЖрдо рддреМрд░ рдкрд░ рд╕рд░рд▓ рд╣реИ, рдПрдХ рдмрдбрд╝реЗ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рднреАрддрд░ рдЖрд╡рд╢реНрдпрдХ рдЕрд╡рдзрд┐ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдСрдкрд░реЗрд╢рди рдХреЛ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдЕрд╡рдзрд┐, рд╕рдореВрд╣ рдореЗрдВ рдмрд╛рдБрдзреЗрдВ рдФрд░ рдпреЛрдЧ рдЬреЛрдбрд╝реЗрдВред


рдЕрдВрддрд░рд╛рд▓ рдХреЗ рднреАрддрд░ рдЕрд╡рдзрд┐рдпреЛрдВ рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВрдиреЗ рдЖрджрддрди рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рд╡рд╛рд▓реА рдХрд╛рд░реНрдпрдкреНрд░рдгрд╛рд▓реА рд▓реА, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдореИрдВ рдЕрдХреНрд╕рд░ рд╕рдВрдЦреНрдпрд╛рддреНрдордХ рдЕрдиреБрдХреНрд░рдо рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░рддрд╛ рд╣реВрдВред рдореИрдВрдиреЗ рддрд╛рд░реАрдЦреЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рджрд╕реНрддрд╛рд╡реЗрдЬ рдХреА рдЬрд╛рдБрдЪ рдХреА, рдПрдХ рдЙрджрд╛рд╣рд░рдг рдорд╛рдирд╛ рдЬрд╛рддрд╛ рд╣реИ, рдПрдХ рдкреНрд░рд╢реНрди рд▓рд┐рдЦрд╛ рдФрд░ рд╣реИрд░рд╛рди рдерд╛ред


select gs::date from generate_series('2018-01-31', '2018-05-31', interval '1 month') as gs; 

gs
2018/01/31
2018/02/28
2018/03/28
2018/04/28
2018/05/28

рдкрд░рд┐рдгрд╛рдо рддрд╛рд░реНрдХрд┐рдХ рдХреЗ рд░реВрдк рдореЗрдВ рдЕрдкреНрд░рддреНрдпрд╛рд╢рд┐рдд рдерд╛ред рдЬрдирд░реЗрдЯ_рд╕рд░реАрдЬ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдХрд╛рд░реНрдп рдХрд░рддреА рд╣реИ, рдХреНрд░рдорд┐рдХ рд░реВрдк рд╕реЗ рдкрд┐рдЫрд▓реЗ рдореВрд▓реНрдп рдХреЗ рд▓рд┐рдП рдПрдХ рдмрджрд▓рд╛рд╡ рдХреЛ рдЬреЛрдбрд╝рдиреЗ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рддрд╛рд░реАрдЦреЛрдВ рдХрд╛ рдПрдХ рдХреНрд░рдо рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред рдЙрд╕реА рд╕рдордп, рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдореЗрдВ, рдкреНрд░рд╛рдкреНрдд рддрд┐рдерд┐ рдХреА рд╢реБрджреНрдзрддрд╛ рдФрд░ рд╕рдВрдкрд╛рджрди рдХреА рдЬрд╛рдБрдЪ рдХреА рдЧрдИ рдереАред 31 рдлрд░рд╡рд░реА рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдЗрд╕рд▓рд┐рдП рддрд╛рд░реАрдЦ 28 рдлрд░рд╡рд░реА рдореЗрдВ рддрдмреНрджреАрд▓ рд╣реЛ рдЧрдИ рдФрд░ рдорд╣реАрдиреЗ рдХреЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдЬреЛрдбрд╝ рдиреЗ рдкреВрд░реЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ 28 рд╡реЗрдВ рд╕реНрдерд╛рди рдкрд░ рд▓рд╛ рджрд┐рдпрд╛ред


рдпреБрдкреАрдбреАред рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЗ рдмрд╛рдж рд╕реНрдкрд╖реНрдЯреАрдХрд░рдгред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдХрд╛рд░реНрдп рд╡реНрдпрд╛рдкрдХ рд╣реИ - рдорд╣реАрдиреЗ рдХреЗ рдордирдорд╛рдиреЗ рджрд┐рдиреЛрдВ рдкрд░ рд╕рдореВрд╣ рдбреЗрдЯрд╛ рдХреЗ рд▓рд┐рдПред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдкреНрд░рддреНрдпреЗрдХ рдорд╛рд╣ рдХреЗ 20 рд╡реЗрдВ рджрд┐рди рддрдХ рд╕рдореВрд╣, 15 рд╡реЗрдВ рджрд┐рди рддрдХ, рд▓реЗрдХрд┐рди рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╕рдордп рдРрд╕реА рддрд┐рдерд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рдХреЛрдИ рд╕рдорд╕реНрдпрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИред рд╣рдо рдЬрд┐рд╕ рддрдВрддреНрд░ рдХреА рддрд▓рд╛рд╢ рдХрд░ рд░рд╣реЗ рд╣реИрдВ, рдЙрд╕реЗ рд╕рдорд╛рди рд░реВрдк рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдорд╛рд╣ рдХреЗ 10 рдирдВрдмрд░реЛрдВ, 21 рдирдВрдмрд░реЛрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХрд╛ рдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП рдФрд░ рдорд╣реАрдиреЛрдВ рдХреЗ рдЕрдВрдд рддрдХ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдПред


рдореБрдЭреЗ рдЖрд╢реНрдЪрд░реНрдп рд╣реИ рдХрд┐ рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдСрдкрд░реЗрд╢рди рдПрдХ рд╕рд╛рде рдХрдИ рдорд╣реАрдиреЛрдВ рдХреЗ рд╕рд╛рде рдХреИрд╕реЗ рд╡реНрдпрд╡рд╣рд╛рд░ рдХрд░реЗрдЧрд╛? рдпрджрд┐ рд╣рдо рдЕрдВрддрд░рд╛рд▓ рдХреЛ рдЬреЛрдбрд╝рдХрд░ рдирд╣реАрдВ, рдмрд▓реНрдХрд┐ "рдереЛрдХ рдореЗрдВ" рдЬреЛрдбрд╝реЗрдВрдЧреЗ рддреЛ рдХреНрдпрд╛ рд╣реЛрдЧрд╛?


 select '2018-01-31'::date +interval '1 mons' 28.02.2018 select '2018-01-31'::date +interval '2 mons' 31.03.2018 

рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛ рдИрдорд╛рдирджрд╛рд░реА рд╕реЗ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред
рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЖрд╡рд╢реНрдпрдХ рддрд┐рдерд┐рдпрд╛рдВ рдХреИрд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд░реЗрдВ?


рдпрджрд┐ рдорд╣реАрдиреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдЬреНрдЮрд╛рдд рд╣реИ, рддреЛ рдпрд╣ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИ:


 select '2018-01-31'::date +make_interval(0, i) as gs from generate_series(0, 4, 1) as i 

gs
2018/01/31
2018/02/28
2018/03/31
2018/04/30
2018/05/31

рдХреНрдпрд╛ рд╣реЛрдЧрд╛ рдпрджрд┐ рдХреЗрд╡рд▓ рдкреНрд░рд╛рд░рдВрдн рддрд┐рдерд┐ рдФрд░ рдЕрдВрддрд┐рдо рддрд┐рдерд┐ рдЬреНрдЮрд╛рдд рд╣реЛ?
рдПрдХ рд╕рдВрдЧреНрд░рд╣рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдФрд░ рдЙрд╕рдореЗрдВ рдПрдХ рд╕рд░рд▓ рдЪрдХреНрд░ рд▓рд┐рдЦрдХрд░ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рдХрд╛рдлреА рдЖрд╕рд╛рдиреА рд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд╣рд╛рд▓рд╛рдВрдХрд┐, рд╣рдо рдПрдХ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рдХрд▓реНрдк рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ рдЬрдм рдЕрдирд╛рд╡рд╢реНрдпрдХ рд╡рд╕реНрддреБрдУрдВ рдХреЗ рд╕рд╛рде рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдВрд░рдЪрдирд╛ рдХреЛ рд░реЛрдХрдирд╛ рдХреЛрдИ рд╕рдВрднрд╛рд╡рдирд╛ рдпрд╛ рдЗрдЪреНрдЫрд╛ рдирд╣реАрдВ рд╣реИред
рдЖрдЗрдП рдкрд┐рдЫрд▓реЗ рдПрдХ рдХрд╛рд░реНрдп рдХреЛ рдХрдо рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред


рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдХреБрдЫ рд╣рдж рддрдХ рдПрдХ рдмреНрд░реЗрдбрдмреЛрд░реНрдб рд╣реИ рдФрд░ рд╕реБрд░реБрдЪрд┐рдкреВрд░реНрдг рд╣реЛрдиреЗ рдХрд╛ рджрд┐рдЦрд╛рд╡рд╛ рдирд╣реАрдВ рдХрд░рддрд╛ рд╣реИ; рд╣рдо рдХрдВрдкрдиреА рдореЗрдВ рдкрд╣рд▓рд╛ рдХреНрд╡реЗрд░реА рд╡рд┐рдХрд▓реНрдк рд▓рд┐рдЦрддреЗ рд╣реИрдВ рдЬрд┐рд╕рдореЗрдВ рдмреНрд▓реЙрдХреЛрдВ рдХреЗ рд▓рдЪреАрд▓реЗрдкрди рдФрд░ рд╡рд┐рдирд┐рдореЗрдпрддрд╛ рдкрд░ рдЬреЛрд░ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред


 /*  -  ,         ,      */ with dates as ( select '2018-01-31'::date as dt1, '2018-05-31'::date as dt2 ), /*      ""  */ g_age as ( select age( (select dt2 from dates), (select dt1 from dates)) ), /*       (*12 + )   +1       */ months as ( select (extract(year from (select * from g_age))*12 + extract(month from (select * from g_age))+1)::integer ), /*  ,           -   ,       */ seq as( select ((select dt1 from dates) + make_interval(0, gs)) as gs from generate_series ( 0, (select * from months), 1 ) as gs where ((select dt1 from dates) + make_interval(0, gs)) <= (select dt2 from dates) ) /*         */ select * from seq 

gs
2018/01/31
2018/02/28
2018/03/31
2018/04/30
2018/05/31

рд╕рдорд╛рдзрд╛рди рдмрд▓реНрдХрд┐ рдмреЛрдЭрд┐рд▓ рд╣реЛ рдЧрдпрд╛, рд▓реЗрдХрд┐рди рдХрд╛рдо рдХрд░ рд░рд╣рд╛ рд╣реИ рдФрд░ рдЗрд╕реЗ рддрдВрддреНрд░ рдХреЗ рд╕рд╛рде рдЕрдиреНрдп рдЕрдиреБрд░реЛрдзреЛрдВ рдореЗрдВ рдПрдХреАрдХреГрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИред
рд╣рдордиреЗ рд░рд┐рдкреЛрд░реНрдЯ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рджрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╡рд┐рдЪрд╛рд░ рдХрд┐ рдпрд╣ рдЕрдиреБрд░реЛрдз рди рдХреЗрд╡рд▓ рдмреЛрдЭрд┐рд▓ рд╣реИ, рдмрд▓реНрдХрд┐ рдкреВрд░реЗ рдорд╣реАрдиреЛрдВ рдореЗрдВ рдХреЗрд╡рд▓ рдЗрд╕рдХреЗ рдЙрдкрдпреЛрдЧ рд╕реЗ рд╕реАрдорд┐рдд рд╣реИ, рдЖрд░рд╛рдо рдирд╣реАрдВ рджрд┐рдпрд╛ред


рд╡рд┐рдХрд▓реНрдк 2
рдереЛрдбрд╝реА рджреЗрд░ рдмрд╛рдж, рдпрд╣ рдореБрдЭ рдкрд░ рд╣рд╛рд╡реА рд╣реЛ рдЧрдпрд╛ рдХрд┐ рдЕрдиреБрдХреНрд░рдорд┐рдХ рддрд┐рдерд┐ рдкреАрдврд╝реА рдЕрдирд┐рд╡рд╛рд░реНрдп рд░реВрдк рд╕реЗ рдПрдХ рдкреБрдирд░рд╛рд╡рд░реНрддреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИред рдХреЗрд╡рд▓ рдЕрдкрдиреЗ рд╢реБрджреНрдз рд░реВрдк рдореЗрдВ рд╣реА рдирд╣реАрдВ, рдХреНрдпреЛрдВрдХрд┐ рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдкрд┐рдЫрд▓реА рдПрдХ рд╕реЗ рдЕрдЧрд▓реА рддрд╛рд░реАрдЦ рдХреА рдЧрдгрдирд╛ рдореВрд▓ рд╕рдорд╕реНрдпрд╛ рдХреА рдУрд░ рд▓реЗ рдЬрд╛рддреА рд╣реИред рд▓реЗрдХрд┐рди рдкреНрд░рддреНрдпреЗрдХ рдЪрд░рдг рдореЗрдВ рд╣рдо рдЕрдкрдиреА рдЕрд╡рдзрд┐ рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рдЬреЛрдбрд╝реЗ рдЧрдП рдЕрдВрддрд░рд╛рд▓ рдХреЛ рдмрдврд╝рд╛ рд╕рдХрддреЗ рд╣реИрдВ:


 /*    -,     timestamp */ with recursive dates as ( select '2018-01-31'::timestamp as dt1, '2018-05-31'::timestamp as dt2, interval '1 month' as interval ), /*           ,          ,   .  ,        */ pr AS( select 1 as i, (select dt1 from dates) as dt union select i+1 as i, ( (select dt1 from dates) + ( select interval from dates)*i)::timestamp as dt from pr where ( ((select dt1 from dates) + (select interval from dates)*i)::timestamp) <=(select dt2 from dates) ) select dt as gs from pr; 

gs
2018/01/31
2018/02/28
2018/03/31
2018/04/30
2018/05/31

рдпрд╣ рдХреНрд╡реЗрд░реА рдХрд┐рд╕реА рднреА рдЗрдирдкреБрдЯ рд╕рдордп рдЕрд╡рдзрд┐ рдФрд░ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде рд╕рд╣реА рдврдВрдЧ рд╕реЗ рдХрд╛рдо рдХрд░рддреА рд╣реИред

Source: https://habr.com/ru/post/hi421969/


All Articles