SQL: рдХрд╛рд░реНрдп рд╕рдордп рдХрд╛рд░реНрдп рд╕рдорд╛рдзрд╛рди

рд╣реИрд▓реЛ, рд░реЗрдбрд┐рдпреЛ рдПрд╕рдХреНрдпреВрдПрд▓ рдлрд┐рд░ рд╕реЗ рд╣рд╡рд╛ рдореЗрдВ рд╣реИ! рдЖрдЬ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЙрд╕ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рдорд╛рдзрд╛рди рд╣реИ рдЬрд┐рд╕реЗ рд╣рдордиреЗ рдЕрдкрдиреЗ рдкрд┐рдЫрд▓реЗ рдкреНрд░рд╕рд╛рд░рдг рдкрд░ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд┐рдпрд╛, рдФрд░ рдЕрдЧрд▓реА рдмрд╛рд░ рдмрд╛рд╣рд░ рдХрд░рдиреЗ рдХрд╛ рд╡рд╛рджрд╛ рдХрд┐рдпрд╛ред рдФрд░ рдпрд╣ рдЕрдЧрд▓реА рдмрд╛рд░ рдЖрдпрд╛ рд╣реИред


рдЗрд╕ рдХрд╛рд░реНрдп рдиреЗ рдорд┐рд▓реНрдХреА рд╡реЗ рдЖрдХрд╛рд╢рдЧрдВрдЧрд╛ рдХреЗ рдорд╛рдирд╡реЛрдВ рдХреЗ рдмреАрдЪ рдПрдХ рдЬреАрд╡рдВрдд рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдкреИрджрд╛ рдХреА (рдФрд░ рдЖрд╢реНрдЪрд░реНрдпрдЬрдирдХ рд░реВрдк рд╕реЗ, рдЙрдирдХреА рд╢реНрд░рдо рджрд╛рд╕рддрд╛ рдХреЗ рд╕рд╛рде, рдЬреЛ рд╡реЗ рдЕрднреА рднреА рд╕рднреНрдпрддрд╛ рдХреЗ рд▓рд╛рдн рдХреЗ рд▓рд┐рдП рд╕рдореНрдорд╛рди рдХрд░рддреЗ рд╣реИрдВ)ред рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рддреАрд╕рд░реЗ рдЧреНрд░рд╣ рдкрд░, Spektr-RG рдЕрдВрддрд░рд┐рдХреНрд╖ рд╡реЗрдзрд╢рд╛рд▓рд╛ рдХрд╛ рдкреНрд░рдХреНрд╖реЗрдкрдг рдЬреБрд▓рд╛рдИ 2019 рдХреЗ рдЕрдВрдд рдореЗрдВ рдЖрд░рд╕реА (рд╕реНрдерд╛рдиреАрдп рдХрд╛рд▓рдХреНрд░рдо) рдХреЛ рд╕реНрдердЧрд┐рдд рдХрд░ рджрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, рдЬрд┐рд╕рдХреА рдорджрдж рд╕реЗ рдЗрд╕ рдХрд╛рд░реНрдпрдХреНрд░рдо рдХреЛ рдкреНрд░рд╕рд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдпреЛрдЬрдирд╛ рдмрдирд╛рдИ рдЧрдИ рдереАред рдореБрдЭреЗ рд╡реИрдХрд▓реНрдкрд┐рдХ рдЯреНрд░рд╛рдВрд╕рдорд┐рд╢рди рдорд╛рд░реНрдЧреЛрдВ рдХреА рддрд▓рд╛рд╢ рдХрд░рдиреА рдереА, рдЬрд┐рд╕рд╕реЗ рд╕рд┐рдЧреНрдирд▓ рдореЗрдВ рдереЛрдбрд╝реА рджреЗрд░реА рд╣реБрдИред рд▓реЗрдХрд┐рди рд╕рдм рдареАрдХ рд╣реИ рдЬреЛ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред



рдореБрдЭреЗ рддреБрд░рдВрдд рдХрд╣рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдХрд╛рд░реНрдп рдХреЗ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдореЗрдВ рдХреЛрдИ рдЬрд╛рджреВ рдирд╣реАрдВ рд╣реЛрдЧрд╛, рдпрд╣рд╛рдВ рдЦреБрд▓рд╛рд╕реЗ рдХреА рдЬрд░реВрд░рдд рдирд╣реАрдВ рд╣реИ рдпрд╛ рдХреБрдЫ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдкреНрд░рднрд╛рд╡реА (рдпрд╛ рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдХреБрдЫ рдХрд┐рд╕реА рдЕрдиреНрдп рдЕрд░реНрде рдореЗрдВ) рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреА рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░реЗрдВред рдпрд╣ рдХреЗрд╡рд▓ рдПрдХ рдкрд╛рд░реНрд╕рд┐рдВрдЧ рдХрд╛рд░реНрдп рд╣реИред рдЗрд╕рдореЗрдВ, рдЬреЛ рд▓реЛрдЧ рдирд╣реАрдВ рдЬрд╛рдирддреЗ рдХрд┐ рдРрд╕реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЗ рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП рдХреИрд╕реЗ рд╕рдВрдкрд░реНрдХ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЙрдиреНрд╣реЗрдВ рдХреИрд╕реЗ рд╣рд▓ рдХрд░рдирд╛ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдпрд╣рд╛рдБ рдХреБрдЫ рднреА рднрдпрд╛рдирдХ рдирд╣реАрдВ рд╣реИред


рдореИрдВ рдЖрдкрдХреЛ рд╢рд░реНрдд рдпрд╛рдж рджрд┐рд▓рд╛ рджреВрдВред

рдЗрд╕рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ рд╕рдорд╛рдкреНрддрд┐ рдХреА рддрд┐рдерд┐-рд╕рдордп (рдкреЛрд╕реНрдЯрдЧреНрд░реЗрдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд┐рдВрдЯреИрдХреНрд╕ рдореЗрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг) рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрдИ рд╕рдордп рдЕрдВрддрд░рд╛рд▓ рд╣реИрдВ:


with periods(id, start_time, stop_time) as ( values(1, '2019-03-29 07:00:00'::timestamp, '2019-04-08 14:00:00'::timestamp), (2, '2019-04-10 07:00:00'::timestamp, '2019-04-10 20:00:00'::timestamp), (3, '2019-04-11 12:00:00'::timestamp, '2019-04-12 16:07:12'::timestamp), (4, '2018-12-28 12:00:00'::timestamp, '2019-01-16 16:00:00'::timestamp) ) 

рдХрд╛рдо рдХреЗ рдШрдВрдЯреЛрдВ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдЕрдВрддрд░рд╛рд▓ рдХреА рдЕрд╡рдзрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдпрд╣ рдПрдХ SQL рдХреНрд╡реЗрд░реА (c) рдореЗрдВ рдЖрд╡рд╢реНрдпрдХ рд╣реИред рд╣рдо рдорд╛рдирддреЗ рд╣реИрдВ рдХрд┐ рд╣рдо рд╕реЛрдорд╡рд╛рд░ рд╕реЗ рд╢реБрдХреНрд░рд╡рд╛рд░ рддрдХ рд╕рдкреНрддрд╛рд╣ рдХреЗ рджрд┐рдиреЛрдВ рдореЗрдВ рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ, рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рд╣рдореЗрд╢рд╛ 10:00 рд╕реЗ 19:00 рддрдХ рд╣реЛрддреЗ рд╣реИрдВред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд░реВрд╕реА рд╕рдВрдШ рдХреЗ рдЙрддреНрдкрд╛рджрди рдХреИрд▓реЗрдВрдбрд░ рдХреЗ рдЕрдиреБрд╕рд╛рд░, рдХрдИ рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдЫреБрдЯреНрдЯрд┐рдпрд╛рдВ рд╣реИрдВ рдЬреЛ рдХрд╛рдо рдХреЗ рджрд┐рди рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рдХреБрдЫ рджрд┐рди рдмрдВрдж рд╣реИрдВ, рдЗрд╕рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЙрдиреНрд╣реАрдВ рдЫреБрдЯреНрдЯрд┐рдпреЛрдВ рдХреЗ рд╕реНрдердЧрд┐рдд рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг рдХрд╛рдо рдХреЗ рджрд┐рди рд╣реИрдВред рдкреВрд░реНрд╡-рдЫреБрдЯреНрдЯреА рдХреЗ рджрд┐рдиреЛрдВ рдХреЛ рдЫреЛрдЯрд╛ рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рд╣реИ, рд╣рдо рдЙрдиреНрд╣реЗрдВ рдкреВрд░рд╛ рдорд╛рдирддреЗ рд╣реИрдВред рдЪреВрдВрдХрд┐ рдЫреБрдЯреНрдЯрд┐рдпрд╛рдВ рд╕рд╛рд▓-рджрд░-рд╕рд╛рд▓ рдмрджрд▓рддреА рд░рд╣рддреА рд╣реИрдВ, рдпрд╛рдиреА рд╕реНрдкрд╖реНрдЯ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЬрд╛рддреА рд╣реИрдВ, рд╣рдо рдХреЗрд╡рд▓ 2018 рдФрд░ 2019 рддрдХ рдЦреБрдж рдХреЛ рд╕реАрдорд┐рдд рд░рдЦреЗрдВрдЧреЗред рдореБрдЭреЗ рдпрдХреАрди рд╣реИ рдХрд┐, рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рд╕рдорд╛рдзрд╛рди рдЖрд╕рд╛рдиреА рд╕реЗ рдкреВрд░рдХ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред


рдкреАрд░рд┐рдпрдбреНрд╕ рд╕реЗ рд╢реБрд░реБрдЖрддреА рдкреАрд░рд┐рдпрдб рддрдХ рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рдореЗрдВ рдПрдХ рдХреЙрд▓рдо рдЬреЛрдбрд╝рдирд╛ рдЬрд░реВрд░реА рд╣реИред рдпрд╣рд╛рдБ рдкрд░рд┐рдгрд╛рдо рд╣реИ:


  id | start_time | stop_time | work_hrs ----+---------------------+---------------------+---------- 1 | 2019-03-29 07:00:00 | 2019-04-08 14:00:00 | 58:00:00 2 | 2019-04-10 07:00:00 | 2019-04-10 20:00:00 | 09:00:00 3 | 2019-04-11 12:00:00 | 2019-04-12 16:07:12 | 13:07:12 4 | 2018-12-28 12:00:00 | 2019-01-16 16:00:00 | 67:00:00 

рд╣рдо рд╢реБрджреНрдзрддрд╛ рдХреЗ рд▓рд┐рдП рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдбреЗрдЯрд╛ рдХреА рдЬрд╛рдВрдЪ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ; рд╣рдо рд╣рдореЗрд╢рд╛ start_time <= stop_time рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ ред


рд╣рд╛рд▓рдд рдХрд╛ рдЕрдВрдд, рдореВрд▓ рдпрд╣рд╛рдБ рд╣реИ: https://habr.com/en/company/postgrespro/blog/448368/ ред


рдпрд╣ рдХрд╛рд░реНрдп рдЗрд╕ рддрдереНрдп рдХреЛ рдПрдХ рдорд╛рдореВрд▓реА рд╡рд┐рдЪрд┐рддреНрд░рддрд╛ рдкреНрд░рджрд╛рди рдХрд░рддрд╛ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдЬрд╛рдирдмреВрдЭрдХрд░ рдПрдХ рд╡рд░реНрдгрдирд╛рддреНрдордХ рд░реВрдк рдореЗрдВ рд╕реНрдерд┐рддрд┐ рдХрд╛ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЖрдзрд╛ рджрд┐рдпрд╛ рд╣реИ (рдЬреИрд╕рд╛ рдХрд┐ рдпрд╣ рдЖрдорддреМрд░ рдкрд░ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдореЗрдВ рд╣реЛрддрд╛ рд╣реИ), рддрдХрдиреАрдХреА рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рдХреЗ рд╡рд┐рд╡реЗрдХ рдХреЛ рдЫреЛрдбрд╝рдХрд░ рдХрд┐ рдЕрдиреБрд╕реВрдЪреА рдХреИрд╕реЗ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХреА рдЬрд╛рдиреА рдЪрд╛рд╣рд┐рдПред рдПрдХ рдУрд░, рдЗрд╕рдХреЗ рд▓рд┐рдП рдХреБрдЫ рд╡рд╛рд╕реНрддреБ рд╕реЛрдЪ рдХреМрд╢рд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИред рдФрд░ рджреВрд╕рд░реА рдУрд░, рдЗрд╕ рдЕрдиреБрд╕реВрдЪреА рдХреЗ рддреИрдпрд╛рд░ рдкреНрд░рд╛рд░реВрдк рдиреЗ рдЗрд╕рдХреЗ рдХреБрдЫ рдЦрд╛рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдкреНрд░реЗрд░рд┐рдд рдХрд┐рдпрд╛ рд╣реЛрдЧрд╛ред рдФрд░ рдпрджрд┐ рдЖрдк рдЪреВрдХ рдЬрд╛рддреЗ рд╣реИрдВ, рддреЛ рд╡рд┐рдЪрд╛рд░ рдФрд░ рдХрд▓реНрдкрдирд╛ рдЕрдзрд┐рдХ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХрд░реЗрдВрдЧреЗред рд░рд┐рд╕реЗрдкреНрд╢рди рдкреВрд░реА рддрд░рд╣ рд╕реЗ рднреБрдЧрддрд╛рди рдХрд┐рдпрд╛ рдЧрдпрд╛, рдЬрд┐рд╕рд╕реЗ рдореБрдЭреЗ рдкреНрд░рдХрд╛рд╢рд┐рдд рд╕рдорд╛рдзрд╛рдиреЛрдВ рдореЗрдВ рднреА рджрд┐рд▓рдЪрд╕реНрдк рджреГрд╖реНрдЯрд┐рдХреЛрдг рдорд┐рд▓ рд╕рдХреЗред


рддреЛ, рдЗрд╕ рддрд░рд╣ рд╕реЗ рдореВрд▓ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рджреЛ рдЙрдк-рдкреНрд░рдХрд╛рд░реЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдирд╛ рд╣реЛрдЧрд╛:


  1. рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░реЗрдВ рдХрд┐ рд╕рдмрд╕реЗ рдЕрдзрд┐рдХ рдХрд╛рдо рдХрд╛ рд╕рдордп рдХреИрд╕реЗ рддрдп рдХрд┐рдпрд╛ рдЬрд╛рдП, рдФрд░ рдпрд╣рд╛рдВ рддрдХ тАЛтАЛрдХрд┐ рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛред
  2. рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдкрд┐рдЫрд▓реЗ рдЙрдкрдорд╛ рд╕реЗ рдХрд╛рдо рдЕрдиреБрд╕реВрдЪреА рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрд░реЛрдд рдХреА рдЕрд╡рдзрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВред

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


рдЕрдЪреНрдЫрд╛, рдЪрд▓рд┐рдПред


рдХрд╛рдо рдХреЗ рдШрдВрдЯреЛрдВ рдореЗрдВ рдЕрд╡рдзрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░реЗрдВ


рдорд╛рдереЗ рдореЗрдВ рдХрд╛рдо рдХреЗ рдШрдВрдЯреЛрдВ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдЕрд╡рдзрд┐ рдХреА рдЕрд╡рдзрд┐ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдЕрдВрддрд░рд╛рд▓ (рдЖрд░реЗрдЦ рдкрд░ рд╣рд░рд╛ рд░рдВрдЧ) рдХреЛ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде рдкрд╛рд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдЬреЛ рдХрд╛рдо рдХреЗ рд╕рдордп (рдирд╛рд░рдВрдЧреА) рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддреЗ рд╣реИрдВред рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рдХреЗ рдЕрдВрддрд░рд╛рд▓ рд╕реЛрдорд╡рд╛рд░ 10:00 рд╕реЗ 19:00, рдордВрдЧрд▓рд╡рд╛рд░ 10:00 рд╕реЗ 19:00 рддрдХ рдФрд░ рдЗрддрдиреЗ рдкрд░ рд╣реИрдВред рдкрд░рд┐рдгрд╛рдо рдиреАрд▓реЗ рд░рдВрдЧ рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:


рдЫрд╡рд┐


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


рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рджреЛрд╣рд░рд╛рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред рд╣рдорд╛рд░реЗ рд▓рд┐рдП рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рдзрд┐рдпрд╛рдБ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдкреАрд░рд┐рдпрдбреНрд╕ рдЯреИрдм (start_time, stop_time) рдореЗрдВ рд╕реЗрдЯ рд╣реИрдВ, рд╣рдо рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдШрдВрдЯреЛрдВ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░реЗрдВрдЧреЗ, рдХрд╣рддреЗ рд╣реИрдВ, рд╢реЗрдбреНрдпреВрд▓ (strat_time, stop_time) , рдЬрд╣рд╛рдБ рд╣рд░ рдХрд╛рд░реНрдп рджрд┐рд╡рд╕ рдореМрдЬреВрдж рд╣реИред рдкрд░рд┐рдгрд╛рдо рдХрд╛рдо рдХреЗ рд╕рдордп рдХреЗ рд╕рднреА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рдзрд┐рдпреЛрдВ рдФрд░ рдЕрдВрддрд░рд╛рд▓реЛрдВ рдХрд╛ рдПрдХ рдкреВрд░реНрдг рдХрд╛рд░реНрдЯреЗрд╢рд┐рдпрди рдЙрддреНрдкрд╛рдж рд╣реИред


рдЕрдВрддрд░ рдХреЛ рд╢рд╛рд╕реНрддреНрд░реАрдп рддрд░реАрдХреЗ рд╕реЗ рдЧрд┐рдирд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЕрдВрддрд░рд╛рд▓ рдХреЛ рдЗрдВрдЯрд░рд╕реЗрдХреНрдЯ рдХрд░рдиреЗ рдХреЗ рд╕рднреА рд╕рдВрднрд╛рд╡рд┐рдд рд╡рд┐рдХрд▓реНрдкреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реБрдП - рд╣рдо рдирд╛рд░рдВрдЧреА рдХреЗ рд╕рд╛рде рд╣рд░реЗ рд░рдВрдЧ рдХреЛ рдХрд╛рдЯрддреЗ рд╣реИрдВ, рдкрд░рд┐рдгрд╛рдо рдиреАрд▓рд╛ рд╣реИ:


рдЫрд╡рд┐


рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рдорд╛рдорд▓реЗ рдореЗрдВ рдкрд░рд┐рдгрд╛рдо рдХреА рд╢реБрд░реБрдЖрдд рдФрд░ рдЕрдВрдд рдХреЗ рд▓рд┐рдП рд╡рд╛рдВрдЫрд┐рдд рдореВрд▓реНрдп рд▓реЗрдирд╛:


  select s.start_time, s.stop_time -- case #1 from periods p, schedule s where p.start_time <= s.start_time and p.stop_time > s.stop_time union all select p.start_time, s.stop_time -- case #2 from periods p, schedule s where p.start_time >= s.start_time and p.stop_time > s.stop_time and p.start_time < s.stop_time union all select s.start_time, p.stop_time -- case #3 from periods p, schedule s where p.start_time <= s.start_time and p.stop_time < s.stop_time and p.stop_time > s.start_time union all select p.start_time, p.stop_time -- case #4 from periods p, schedule s where p.start_time >= s.start_time and p.stop_time < s.stop_time 

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


рдЖрдк рдЕрдиреНрдпрдерд╛ PostgreSQL рдореЗрдВ рдЙрдкрд▓рдмреНрдз tsrange рд░реЗрдВрдЬ рдкреНрд░рдХрд╛рд░ рдФрд░ рдЗрд╕рдХреЗ рд▓рд┐рдП рдкрд╣рд▓реЗ рд╕реЗ рдЙрдкрд▓рдмреНрдз рдЪреМрд░рд╛рд╣реЗ рдСрдкрд░реЗрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


  select tsrange(s.start_time, s.stop_time) * tsrange(s.start_time, s.stop_time) from periods p, schedule s 

рд╕рд╣рдордд рд╣реВрдБ рдХрд┐ рдЗрддрдирд╛ - рдЙрд╣ - рдереЛрдбрд╝рд╛ рдЖрд╕рд╛рдиред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, PostgreSQL рдореЗрдВ рдРрд╕реА рдмрд╣реБрдд рд╕реА рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдЫреЛрдЯреА рдЪреАрдЬреЗрдВ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рдЗрд╕ рдкрд░ рдкреНрд░рд╢реНрди рд▓рд┐рдЦрдирд╛ рдмрд╣реБрдд рдЕрдЪреНрдЫрд╛ рд╣реИред


рдХреИрд▓реЗрдВрдбрд░ рдЬрдирд░реЗрдЯ рдХрд░реЗрдВ


рдЕрдм рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рдХреА рдЕрдиреБрд╕реВрдЪреА рдХреЗ рд╕рд╛рде рдЙрдк-рдХрд╛рд░реНрдп рдкрд░ рд╡рд╛рдкрд╕ рдЬрд╛рдПрдВред


рд╣рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХрд╛рд░реНрдп рджрд┐рд╡рд╕ рдХреЗ рд▓рд┐рдП 10:00 рд╕реЗ 19:00 рддрдХ рдХрд╛рд░реНрдп рд╕рдордп рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рд░реНрдп рдЕрдиреБрд╕реВрдЪреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдЕрдиреБрд╕реВрдЪреА (start_time, stop_time) рдХреА рддрд░рд╣ рдХреБрдЫред рдЬреИрд╕рд╛ рдХрд┐ рд╣рдордиреЗ рд╕рдордЭрд╛, рдпрд╣ рд╣рдорд╛рд░реА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реЛрдЧрд╛ред рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдЬреАрд╡рди рдореЗрдВ, рдЗрд╕ рддрд░рд╣ рдХреЗ рд╢реЗрдбреНрдпреВрд▓ рдХреЛ рдЯреЗрдмрд▓ рд╕реЗрдЯ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рджреЛ рд╕рд╛рд▓ рдХреЗ рд▓рд┐рдП рдпрд╣ рдХреЗрд╡рд▓ 500 рд░рд┐рдХреЙрд░реНрдб рд╣реИ, рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдЙрджреНрджреЗрд╢реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдпрд╣ рджрд╕ рд╕рд╛рд▓ рднреА рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрдЧрд╛ - рдпрд╣ рдПрдХ рдФрд░ рдбреЗрдврд╝ рд╣рдЬрд╛рд░ рд░рд┐рдХреЙрд░реНрдб рд╣реИ, рдЖрдзреБрдирд┐рдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЗ рд▓рд┐рдП рдЕрд╕рд▓реА рдмрдХрд╡рд╛рд╕ред рд▓реЗрдХрд┐рди рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рд╕рдорд╕реНрдпрд╛ рд╣реИ рдЬрд┐рд╕реЗ рдПрдХ рдЕрдиреБрд░реЛрдз рдореЗрдВ рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдЗрд╕рдореЗрдВ рдРрд╕реА рдкреВрд░реА рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рд╕реВрдЪреАрдмрджреНрдз рдХрд░рдирд╛ рдмрд╣реБрдд рд╡реНрдпрд╛рд╡рд╣рд╛рд░рд┐рдХ рдирд╣реАрдВ рд╣реИред рдЖрдЗрдП рдЗрд╕реЗ рдФрд░ рдЕрдзрд┐рдХ рдХреЙрдореНрдкреИрдХреНрдЯ рд░реВрдк рд╕реЗ рд▓рд╛рдЧреВ рдХрд░рдиреЗ рдХрд╛ рдкреНрд░рдпрд╛рд╕ рдХрд░реЗрдВред


рдХрд┐рд╕реА рднреА рдорд╛рдорд▓реЗ рдореЗрдВ, рд╣рдореЗрдВ рдЙрдиреНрд╣реЗрдВ рдмреЗрд╕ рд╢реЗрдбреНрдпреВрд▓ рд╕реЗ рд╣рдЯрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЫреБрдЯреНрдЯрд┐рдпреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдФрд░ рдпрд╣рд╛рдВ рдХреЗрд╡рд▓ рд▓рд┐рд╕реНрдЯрд┐рдВрдЧ рдЙрдкрдпреБрдХреНрдд рд╣реИ:


  dates_exclude(d) as ( values('2018-01-01'::date), -- 2018 ('2018-01-02'::date), ('2018-01-03'::date), ('2018-01-04'::date), ('2018-01-05'::date), ('2018-01-08'::date), ('2018-02-23'::date), ('2018-03-08'::date), ('2018-03-09'::date), ('2018-05-01'::date), ('2018-05-02'::date), ('2018-05-09'::date), ('2018-06-11'::date), ('2018-06-12'::date), ('2018-11-05'::date), ('2018-12-31'::date), ('2019-01-01'::date), -- 2019 ('2019-01-02'::date), ('2019-01-03'::date), ('2019-01-04'::date), ('2019-01-07'::date), ('2019-01-08'::date), ('2019-03-08'::date), ('2019-05-01'::date), ('2019-05-02'::date), ('2019-05-03'::date), ('2019-05-09'::date), ('2019-05-10'::date), ('2019-06-12'::date), ('2019-11-04'::date) ) 

рдФрд░ рдЕрддрд┐рд░рд┐рдХреНрдд рд╡реНрдпрд╛рд╡рд╕рд╛рдпрд┐рдХ рджрд┐рдиреЛрдВ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛:


  dates_include(d) as ( values --  2018,  2019  ('2018-04-28'::date), ('2018-06-09'::date), ('2018-12-29'::date) ) 

рджреЛ рд╕рд╛рд▓ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рджрд┐рд╡рд╕реЛрдВ рдХрд╛ рдХреНрд░рдо рдПрдХ рд╡рд┐рд╢реЗрд╖ рдФрд░ рдмрд╣реБрдд рд╣реА рдЙрдкрдпреБрдХреНрдд рдЬрдирд░реЗрдЯ__рд░реЗ () рдлрд╝рдВрдХреНрд╢рди рджреНрд╡рд╛рд░рд╛ рдЙрддреНрдкрдиреНрди рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕ рддрд░рд╣ рд╕реЗ рд╢рдирд┐рд╡рд╛рд░ рдФрд░ рд░рд╡рд┐рд╡рд╛рд░ рдХреЛ рддреБрд░рдВрдд рдлреЗрдВрдХ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ:


  select d from generate_series( '2018-01-01'::timestamp , '2020-01-01'::timestamp , '1 day'::interval ) as d where extract(dow from d) not in (0,6) --     

рд╣рдо рд╕рдм рдХреБрдЫ рдПрдХ рд╕рд╛рде рдЬреЛрдбрд╝рдХрд░ рдХрд╛рд░реНрдп рджрд┐рд╡рд╕ рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВ: рд╣рдо рджреЛ рд╡рд░реНрд╖реЛрдВ рдореЗрдВ рд╕рднреА рдХрд╛рд░реНрдп рджрд┐рд╡рд╕реЛрдВ рдХрд╛ рдПрдХ рдХреНрд░рдо рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ, date_include рд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдХрд╛рд░реНрдп рджрд┐рд╡рд╕ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ рдФрд░ date_exclude рд╕реЗ рд╕рднреА рдЕрддрд┐рд░рд┐рдХреНрдд рджрд┐рдиреЛрдВ рдХреЛ рдирд┐рдХрд╛рд▓рддреЗ рд╣реИрдВ :


  schedule_base as ( select d from generate_series( '2018-01-01'::timestamp , '2020-01-01'::timestamp , '1 day'::interval ) as d where extract(dow from d) not in (0,6) --     union select d from dates_include --     except select d from dates_exclude --     ) 

рдФрд░ рдЕрдм рд╣рдореЗрдВ рд╕рдордп рдЕрдВрддрд░рд╛рд▓ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:


  schedule(start_time, stop_time) as ( select d + '10:00:00'::time, d + '19:00:00'::time from schedule_base ) 

рдЗрд╕рд▓рд┐рдП, рд╣рдореЗрдВ рд╢реЗрдбреНрдпреВрд▓ рдорд┐рд▓рд╛ред


рдпрд╣ рд╕рдм рдПрдХ рд╕рд╛рде рд░рдЦрдирд╛


рдЕрдм рд╣рдореЗрдВ рдЪреМрд░рд╛рд╣реЗ рдорд┐рд▓реЗрдВрдЧреЗ:


  select p.* , tsrange(p.start_time, p.stop_time) * tsrange(s.start_time, s.stop_time) as wrkh from periods p join schedule s on tsrange(p.start_time, p.stop_time) && tsrange(s.start_time, s.stop_time) 

рдХрдиреЗрдХреНрд╢рди рд╕реНрдерд┐рддрд┐ рдкрд░ рдзреНрдпрд╛рди рджреЗрдВ, рдпрд╣ рд╕рдореНрдорд┐рд▓рд┐рдд рддрд╛рд▓рд┐рдХрд╛рдУрдВ рд╕реЗ рджреЛ рд╕рдВрдмрдВрдзрд┐рдд рд░рд┐рдХреЙрд░реНрдб рд╕реЗ рдореЗрд▓ рдирд╣реАрдВ рдЦрд╛рддрд╛ рд╣реИ, рдРрд╕рд╛ рдкрддреНрд░рд╛рдЪрд╛рд░ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИ, рд▓реЗрдХрд┐рди рдХреБрдЫ рдЕрдиреБрдХреВрд▓рди рдкреЗрд╢ рдХрд┐рдП рдЧрдП рд╣реИрдВ рдЬреЛ рдХрд╛рдо рдХреЗ рд╕рдордп рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдХреЛ рдХрд╛рдЯрддреЗ рд╣реИрдВ, рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░реА рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рдзрд┐ рдЕрдВрддрд░ рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдпрд╣ && рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬреЛ tsrange рдЕрдВрддрд░рд╛рд▓ рдХреЗ рдЪреМрд░рд╛рд╣реЗ рдХреА рдЬрд╛рдВрдЪ рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдмрд╣реБрдд рд╕рд╛рд░реЗ рдЦрд╛рд▓реА рдЪреМрд░рд╛рд╣реЛрдВ рдХреЛ рд╣рдЯрд╛рддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЖрдВрдЦреЛрдВ рдХреЗ рд░рд╛рд╕реНрддреЗ рдореЗрдВ рди рдЖрдП, рд▓реЗрдХрд┐рди, рджреВрд╕рд░реА рдУрд░, рдЙрди рд╢реБрд░реБрдЖрддреА рдЕрд╡рдзрд┐рдпреЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЬрд╛рдирдХрд╛рд░реА рдХреЛ рд╣рдЯрд╛ рджреЗрддрд╛ рд╣реИ рдЬреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдмрдВрдж рд╣реЛ рдЬрд╛рддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рд╣рдорд╛рд░рд╛ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдФрд░ рдЕрдиреБрд░реЛрдз рдХреЛ рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд▓рд┐рдЦрддрд╛ рд╣реИ:


  periods_wrk as ( select p.* , tsrange(p.start_time, p.stop_time) * tsrange(s.start_time, s.stop_time) as wrkh from periods p , schedule s ) select id, start_time, stop_time , sum(upper(wrkh)-lower(wrkh)) from periods_wrk group by id, start_time, stop_time 

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


рд╕рдм рдХреБрдЫ, рдкрд░рд┐рдгрд╛рдо рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рдореИрдВ рдЦрд╛рд▓реА рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд▓рд┐рдП NULL рдорд╛рдиреЛрдВ рдХреА рддрд░рд╣ рдирд╣реАрдВ рдерд╛, рдХреНрд╡реЗрд░реА рдХреЛ рд╢реВрдиреНрдп-рд▓рдВрдмрд╛рдИ рдЕрдВрддрд░рд╛рд▓ рдХреЛ рдмреЗрд╣рддрд░ рджрд┐рдЦрд╛рдиреЗ рджреЗрдВред рдорд╛рддреНрд░рд╛ рдореЗрдВ рд▓рдкреЗрдЯреЗрдВ () :


 select id, start_time, stop_time , coalesce(sum(upper(wrkh)-lower(wrkh)), '0 sec'::interval) from periods_wrk group by id, start_time, stop_time 

рд╕рднреА рдорд┐рд▓рдХрд░ рдЕрдВрддрд┐рдо рдкрд░рд┐рдгрд╛рдо рджреЗрддреЗ рд╣реИрдВ:


 with periods(id, start_time, stop_time) as ( values(1, '2019-03-29 07:00:00'::timestamp, '2019-04-08 14:00:00'::timestamp) , (2, '2019-04-10 07:00:00'::timestamp, '2019-04-10 20:00:00'::timestamp) , (3, '2019-04-11 12:00:00'::timestamp, '2019-04-12 16:00:00'::timestamp) , (4, '2018-12-28 12:00:00'::timestamp, '2019-01-16 16:00:00'::timestamp) ), dates_exclude(d) as ( values('2018-01-01'::date), -- 2018 ('2018-01-02'::date), ('2018-01-03'::date), ('2018-01-04'::date), ('2018-01-05'::date), ('2018-01-08'::date), ('2018-02-23'::date), ('2018-03-08'::date), ('2018-03-09'::date), ('2018-05-01'::date), ('2018-05-02'::date), ('2018-05-09'::date), ('2018-06-11'::date), ('2018-06-12'::date), ('2018-11-05'::date), ('2018-12-31'::date), ('2019-01-01'::date), -- 2019 ('2019-01-02'::date), ('2019-01-03'::date), ('2019-01-04'::date), ('2019-01-07'::date), ('2019-01-08'::date), ('2019-03-08'::date), ('2019-05-01'::date), ('2019-05-02'::date), ('2019-05-03'::date), ('2019-05-09'::date), ('2019-05-10'::date), ('2019-06-12'::date), ('2019-11-04'::date) ), dates_include(start_time, stop_time) as ( values --  2018,  2019  ('2018-04-28 10:00:00'::timestamp, '2018-04-28 19:00:00'::timestamp), ('2018-06-09 10:00:00'::timestamp, '2018-06-09 19:00:00'::timestamp), ('2018-12-29 10:00:00'::timestamp, '2018-12-29 19:00:00'::timestamp) ) ), schedule_base(start_time, stop_time) as ( select d::timestamp + '10:00:00', d::timestamp + '19:00:00' from generate_series( (select min(start_time) from periods)::date::timestamp , (select max(stop_time) from periods)::date::timestamp , '1 day'::interval ) as days(d) where extract(dow from d) not in (0,6) ), schedule as ( select * from schedule_base where start_time::date not in (select d from dates_exclude) union select * from dates_include ), periods_wrk as ( select p.* , tsrange(p.start_time, p.stop_time) * tsrange(s.start_time, s.stop_time) as wrkh from periods p , schedule s ) select id, start_time, stop_time , sum(coalesce(upper(wrkh)-lower(wrkh), '0 sec'::interval)) from periods_wrk group by id, start_time, stop_time 

рд╣реБрд░реНрд░реЗ! .. рдпрд╣ рд╕рдорд╛рдкреНрдд рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкреВрд░реНрдгрддрд╛ рдХреЗ рд▓рд┐рдП рд╣рдо рдХреБрдЫ рдФрд░ рд╕рдВрдмрдВрдзрд┐рдд рд╡рд┐рд╖рдпреЛрдВ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВрдЧреЗред


рд╡рд┐рд╖рдп рдХрд╛ рдФрд░ рд╡рд┐рдХрд╛рд╕


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


рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЖрдк рд╕рдкреНрддрд╛рд╣ рдХреЗ рджрд┐рди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдПрдХ рдХрд╛рд░реНрдп рджрд┐рд╡рд╕ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдкреНрд░рд╛рд░рдВрдн рдФрд░ рд╕рдорд╛рдкреНрддрд┐ рд╕рдордп рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:


  select d + case extract(dow from d) when 1 then '10:00:00'::time --  when 2 then '11:00:00'::time --  when 3 then '11:00:00'::time --  --        else '10:00:00'::time end , d + case extract(dow from d) --   19   when 5 then '14:00:00'::time --  else '19:00:00'::time end from schedule_base 

рдпрджрд┐ рдЖрдкрдХреЛ 13:00 рд╕реЗ 14:00 рддрдХ рд▓рдВрдЪ рдмреНрд░реЗрдХ рдХрд╛ рдзреНрдпрд╛рди рд░рдЦрдирд╛ рд╣реИ, рддреЛ рдкреНрд░рддрд┐ рджрд┐рди рдПрдХ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рдмрдЬрд╛рдп, рджреЛ рдХрд░реЗрдВ:


  select d + '10:00:00'::time , d + '13:00:00'::time from schedule_base union all select d + '14:00:00'::time , d + '19:00:00'::time from schedule_base 

рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ рдФрд░ рдЗрддрдиреЗ рдкрд░ред


рдЙрддреНрдкрд╛рджрдХрддрд╛


рдореИрдВ рдкреНрд░рджрд░реНрд╢рди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреБрдЫ рд╢рдмреНрдж рдХрд╣реВрдВрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рд╣рдореЗрд╢рд╛ рдЗрд╕рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рд╕рд╡рд╛рд▓ рд╣реЛрддреЗ рд╣реИрдВред рдореИрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдмрд╣реБрдд рдЪрдмрд╛рдиреЗ рд╡рд╛рд▓рд╛ рдирд╣реАрдВ рд╣реВрдВ, рдпрд╣ рдПрдХ рддрд╛рд░рд╛рдВрдХрди рдЪрд┐рд╣реНрди рд╡рд╛рд▓рд╛ рдЦрдВрдб рд╣реИред


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


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


рд▓реЗрдХрд┐рди рдЕрдиреБрд░реЛрдз рдореЗрдВ рдЕрдирд╛рд╡рд╢реНрдпрдХ рдХрд╛рдо рдирд╣реАрдВ рдХрд░рдирд╛ рд╕рд╣реА рд╣реИ, рдЖрдкрдХреЛ рд╣рдореЗрд╢рд╛ рдЗрд╕реЗ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░рдиреА рдЪрд╛рд╣рд┐рдПред


рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░, рд╣рдо рдХреНрд╡реЗрд░реА рдореЗрдВ рдПрдХ рдСрдкреНрдЯрд┐рдорд╛рдЗрдЬрд╝реЗрд╢рди рдХреЛ рддреБрд░рдВрдд рд╢рд╛рдорд┐рд▓ рдХрд░реЗрдВрдЧреЗ - рдкреНрд░рддреНрдпреЗрдХ рд╕реЛрд░реНрд╕ рдкреАрд░рд┐рдпрдб рдХреЛ рдХреЗрд╡рд▓ рдЙрди рд╡рд░реНрдХрд┐рдВрдЧ рдЯрд╛рдЗрдо рдЕрдВрддрд░рд╛рд▓реЛрдВ рдХреЗ рд╕рд╛рде рдЗрдВрдЯрд░рд╕реЗрдХреНрдЯ рдХрд░рдиреЗ рджреЗрдВ, рдЬрд┐рдирдХреЗ рд╕рд╛рде рдЗрд╕рдХреЗ рдХреЙрдорди рдкреЙрдЗрдВрдЯреНрд╕ (рд░реЗрдВрдЬ рд╕реАрдорд╛рдУрдВ рдкрд░ рд▓рдВрдмреА рд╢рд╛рд╕реНрддреНрд░реАрдп рд╕реНрдерд┐рддрд┐ рдХреЗ рдмрдЬрд╛рдп, рдпрд╣ tsrange рдЯрд╛рдЗрдк рдХреЗ рд▓рд┐рдП рдмрд┐рд▓реНрдЯ-рдЗрди && рдСрдкрд░реЗрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЕрдзрд┐рдХ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИ)ред рдпрд╣ рдЕрдиреБрдХреВрд▓рди рдкрд╣рд▓реЗ рд╣реА рдЕрдиреБрд░реЛрдз рдореЗрдВ рджрд┐рдЦрд╛рдИ рджреЗ рдЪреБрдХрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЗрд╕ рддрдереНрдп рдХреЗ рдХрд╛рд░рдг рд╣реИ рдХрд┐ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЕрд╡рдзрд┐ рдЬреЛ рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдХрд╛рдо рдХреЗ рдШрдВрдЯреЛрдВ рд╕реЗ рдмрд╛рд╣рд░ рд╣реЛ рдЧрдИ рдереА, рдкрд░рд┐рдгрд╛рдореЛрдВ рд╕реЗ рдЧрд╛рдпрдм рд╣реЛ рдЧрдИред


рдЗрд╕ рдЕрдиреБрдХреВрд▓рди рдХреЛ рд╡рд╛рдкрд╕ рд▓рд╛рдПрдВред рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, LEFT JOIN рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВ, рдЬреЛ рдкреАрд░рд┐рдпрдбреНрд╕ рдЯреЗрдмрд▓ рдХреЗ рд╕рднреА рд░рд┐рдХреЙрд░реНрдб рдХреЛ рдмрдЪрд╛рдПрдЧрд╛ред рдЕрдм period_wrk рд╕рдмрдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:


 , periods_wrk as ( select p.* , tsrange(p.start_time, p.stop_time) * tsrange(s.start_time, s.stop_time) as wrkh from periods p left join schedule s on tsrange(p.start_time, p.stop_time) && tsrange(s.start_time, s.stop_time)) 

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


рдкреБрд░рд╛рдиреА рдХреНрд╡реЗрд░реА:


 explain (analyse) with periods(id, start_time, stop_time) as ( ... QUERY PLAN ------------------------------------------------------------------------------------ HashAggregate (cost=334.42..338.39 rows=397 width=36) (actual time=10.724..10.731 rows=4 loops=1) ... 

рдирдИ:


 explain (analyse) with periods(id, start_time, stop_time) as ( ... QUERY PLAN ------------------------------------------------------------------------------------ HashAggregate (cost=186.37..186.57 rows=20 width=36) (actual time=5.431..5.440 rows=4 loops=1) ... 

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


рдФрд░ рдЗрд╕ рдкрд░ рдореИрдВ рдЕрдиреБрдХреВрд▓рди рдХреЗ рд╕рд╛рде рд░реБрдХ рдЬрд╛рдКрдВрдЧрд╛ред рдЬрдм рдореИрдВрдиреЗ рдЕрдкрдиреЗ рд▓рд┐рдП рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛, рддреЛ рдореЗрд░реЗ рдкрд╛рд╕ рдЗрд╕ рдЕрдиреБрд░реЛрдз рдХреЗ рдмрд╣реБрдд рдЕрдзрд┐рдХ рднрдпрд╛рдирдХ рд░реВрдк рдореЗрдВ рднреА рдкрд░реНрдпрд╛рдкреНрдд рдкреНрд░рджрд░реНрд╢рди рдерд╛, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдЕрдиреБрдХреВрд▓рди рдХреА рдХреЛрдИ рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рдереАред рдПрдХ рдмрд╛рд░ рдПрдХ рддрд┐рдорд╛рд╣реА рдореЗрдВ рдЕрдкрдиреЗ рдбреЗрдЯрд╛ рдкрд░ рдПрдХ рд░рд┐рдкреЛрд░реНрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдореИрдВ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рджрд╕ рд╕реЗрдХрдВрдб рдкреНрд░рддреАрдХреНрд╖рд╛ рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВред рдРрд╕реА рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдЕрдиреБрдХреВрд▓рди рдкрд░ рдмрд┐рддрд╛рдП рдЧрдП рдЕрддрд┐рд░рд┐рдХреНрдд рдШрдВрдЯреЗ рдХрд╛ рднреБрдЧрддрд╛рди рдХрднреА рдирд╣реАрдВ рд╣реЛрдЧрд╛ред


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


рдкрд╣рд▓реА рдмрд╛рдд рдЬреЛ рджрд┐рдорд╛рдЧ рдореЗрдВ рдЖрддреА рд╣реИ, рдЙрд╕реЗ рдПрдХ рдмрд╛рд░ рдЧрд┐рдирдирд╛ рдФрд░ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдХрд╛рдо рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдХреЗ рд╕рд╛рде рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рд░рдЦрдирд╛ рд╣реИред рдорддрднреЗрдж рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ: рдпрджрд┐ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рдмрджрд▓рд╛ рдирд╣реАрдВ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╛ рдРрд╕реА рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдкреНрд░рд╛рд╕рдВрдЧрд┐рдХ рдбреЗрдЯрд╛ рдХреЗ рд╕рдорд░реНрдерди рд╕реЗ рдХрдард┐рдирд╛рдЗрдпреЛрдВ рдХреА рдЙрдореНрдореАрдж рдХреА рдЬрд╛рддреА рд╣реИред рдлрд┐рд░ рдЖрдкрдХреЛ рдЕрдиреБрд░реЛрдз рдХреЗ рд░реВрдк рдореЗрдВ "рдЙрдбрд╝рдиреЗ рдкрд░" рд╕рдордп рдХреА рдкреАрдврд╝реА рдХреЛ рдЫреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛, рдХреНрдпреЛрдВрдХрд┐ рдпрд╣ рдмрд╣реБрдд рднрд╛рд░реА рдЙрдкрд╢реНрд░реЗрдгреА рдирд╣реАрдВ рд╣реИред


рдЕрдЧрд▓рд╛ рдФрд░ рд╕рдмрд╕реЗ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА (рд▓реЗрдХрд┐рди рд╣рдореЗрд╢рд╛ рд▓рд╛рдЧреВ рдирд╣реАрдВ) рджреГрд╖реНрдЯрд┐рдХреЛрдг рдПрд▓реНрдЧреЛрд░рд┐рджрдо рдЕрдиреБрдХреВрд▓рди рд╣реИред рдЗрдирдореЗрдВ рд╕реЗ рдХреБрдЫ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдкрд╣рд▓реЗ рд╣реА рд╕рдорд╕реНрдпрд╛ рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рд▓реЗрдЦ рдореЗрдВ рдЯрд┐рдкреНрдкрдгрд┐рдпреЛрдВ рдореЗрдВ рдкреНрд░рд╕реНрддреБрдд рдХрд┐рдП рдЧрдП рд╣реИрдВред


рдореБрдЭреЗ рдпрд╣ рд╕рдмрд╕реЗ рдЬреНрдпрд╛рджрд╛ рдкрд╕рдВрдж рд╣реИред рдпрджрд┐ рдЖрдк рдХреИрд▓реЗрдВрдбрд░ рдХреЗ рд╕рднреА (рди рдХреЗрд╡рд▓ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ) рджрд┐рдиреЛрдВ рдХреЗ рд╕рд╛рде рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рддреЗ рд╣реИрдВ рдФрд░ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд "рджреБрдирд┐рдпрд╛ рдХреЗ рдирд┐рд░реНрдорд╛рдг" рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рджрд┐рди рдХрд┐рддрдиреЗ рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рдХреА рд╕рдВрдЪрдпреА рдХреБрд▓ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдПрдХ рд╕реВрдХреНрд╖реНрдорддрд╛ рдСрдкрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рджреЛ рддрд┐рдерд┐рдпреЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рдХреЗрд╡рд▓ рдкрд╣рд▓реЗ рдФрд░ рдЕрдВрддрд┐рдо рджрд┐рди рдХреЗ рд▓рд┐рдП рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рдХреЛ рд╕рд╣реА рдврдВрдЧ рд╕реЗ рд▓реЗрдиреЗ рдХреЗ рд▓рд┐рдП рд░рд╣рддрд╛ рд╣реИ - рдФрд░ рдЖрдк рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдпрд╣рд╛рдБ рдЗрд╕ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдореЗрдВ рдореБрдЭреЗ рдХреНрдпрд╛ рдорд┐рд▓рд╛ рд╣реИ:


  schedule_base(d, is_working) as ( select '2018-01-01'::date, 0 union all select d+1, case when extract(dow from d+1) not in (0,6) and d+1 <> all('{2019-01-01,2019-01-02,2019-01-03,2019-01-04,2019-01-07,2019-01-08,2019-03-08,2019-05-01,2019-05-02,2019-05-03,2019-05-09,2019-05-10,2019-06-12,2019-11-04,2018-01-01,2018-01-02,2018-01-03,2018-01-04,2018-01-05,2018-01-08,2018-02-23,2018-03-08,2018-03-09,2018-04-30,2018-05-01,2018-05-02,2018-05-09,2018-06-11,2018-06-12,2018-11-05,2018-12-31}') or d+1 = any('{2018-04-28,2018-06-09,2018-12-29}') then 1 else 0 end from schedule_base where d < '2020-01-01' ), schedule(d, is_working, work_hours) as ( select d, is_working , sum(is_working*'9 hours'::interval) over (order by d range between unbounded preceding and current row) from schedule_base ) select p.* , s2.work_hours - s1.work_hours + ('19:00:00'::time - least(greatest(p.start_time::time, '10:00:00'::time), '19:00:00'::time)) * s1.is_working - ('19:00:00'::time - least(greatest(p.stop_time::time, '10:00:00'::time), '19:00:00'::time)) * s2.is_working as wrk from periods p, schedule s1, schedule s2 where s1.d = p.start_time::date and s2.d = p.stop_time::date 

рдореИрдВ рдпрд╣рд╛рдВ рд╕рдВрдХреНрд╖реЗрдк рдореЗрдВ рдмрддрд╛рдКрдВрдЧрд╛ рдХрд┐ рдХреНрдпрд╛ рд╣реЛ рд░рд╣рд╛ рд╣реИред рд╢реЗрдбреНрдпреВрд▓_рдмреЗрд╕ рд╕рдмрдХреНрд╡реЗрд░реА рдореЗрдВ, рд╣рдо рдХреИрд▓реЗрдВрдбрд░ рдХреЗ рд╕рднреА рджрд┐рдиреЛрдВ рдХреЛ рджреЛ рд╡рд░реНрд╖реЛрдВ рдХреЗ рд▓рд┐рдП рдЙрддреНрдкрдиреНрди рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдкреНрд░рддреНрдпреЗрдХ рджрд┐рди рд╣рдо рдпрд╣ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдХрд╛рд░реНрдп рджрд┐рд╡рд╕ (= 1) рд╣реИ рдпрд╛ рдирд╣реАрдВ (= 0)ред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рд╢реЗрдбреНрдпреВрд▓ рд╕рдмрдХреНрд╡реЗрд░реА рдореЗрдВ, рд╣рдо рд╡рд┐рдВрдбреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЛ 2018-01-01 рд╕реЗ рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рдХреА рдХреБрд▓ рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рдорд╛рдирддреЗ рд╣реИрдВред рд╕рдмрдХреБрдЫ рдПрдХ рдЙрдк-рд╡рд░реНрдЧ рдореЗрдВ рдХрд░рдирд╛ рд╕рдВрднрд╡ рд╣реЛрдЧрд╛, рд▓реЗрдХрд┐рди рдпрд╣ рдЕрдзрд┐рдХ рдмреЛрдЭрд┐рд▓ рд╣реЛ рдЬрд╛рдПрдЧрд╛, рдЬреЛ рдкрдардиреАрдпрддрд╛ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░реЗрдЧрд╛ред рдлрд┐рд░, рдореБрдЦреНрдп рдЕрдиреБрд░реЛрдз рдореЗрдВ, рд╣рдо рдЕрд╡рдзрд┐ рдХреЗ рдЕрдВрдд рдФрд░ рд╢реБрд░реБрдЖрдд рдореЗрдВ рдХрд╛рдо рдХреЗ рдШрдВрдЯреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЗ рдмреАрдЪ рдХреЗ рдЕрдВрддрд░ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдХреБрдЫ рд╣рдж рддрдХ, рдЗрд╕ рдЕрд╡рдзрд┐ рдХреЗ рдкрд╣рд▓реЗ рдФрд░ рдЖрдЦрд┐рд░реА рджрд┐рди рдХреЗ рдХрд╛рдо рдХреЗ рдШрдВрдЯреЗ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реИрдВред рдХрд╛рд░реНрдпрджрд┐рд╡рд╕ рдХреА рд╢реБрд░реБрдЖрдд рд╕реЗ рдкрд╣рд▓реЗ рдХреЗ рд╕рдордп рдХреЛ рдФрд░ рдЗрд╕рдХреА рд╕рдорд╛рдкреНрддрд┐ рдХреЗ рдмрд╛рдж рдХрд╛рд░реНрдп рджрд┐рд╡рд╕ рдХреА рд╕рдорд╛рдкреНрддрд┐ рдХреЗ рдмрд╛рдж рдХреЗ рд╕рдордп рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рдиреЗ рд╕реЗ рдЬреБрдбрд╝реА рд╣реБрдИ рд╣реИред рдЗрд╕рдХреЗ рдЕрд▓рд╛рд╡рд╛, рдЕрдЧрд░ shedule_base рдФрд░ рд╢реЗрдбреНрдпреВрд▓ рдХреЗ рд╕рд╛рде рдЕрдиреБрд░реЛрдз рдХрд╛ рд╣рд┐рд╕реНрд╕рд╛ рдПрдХ рдЕрд▓рдЧ рдкреВрд░реНрд╡-рдкрд░рд┐рдХрд▓рд┐рдд рддрд╛рд▓рд┐рдХрд╛ (рдЬреИрд╕рд╛ рдХрд┐ рдкрд╣рд▓реЗ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдореЗрдВ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ рдпрд╣ рдЕрдиреБрд░реЛрдз рдкреВрд░реА рддрд░рд╣ рд╕реЗ рдПрдХ рддреБрдЪреНрдЫ рдореЗрдВ рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред


рдЖрдЗрдП рдПрдХ рдмрдбрд╝реЗ рдирдореВрдиреЗ рдкрд░ рдирд┐рд╖реНрдкрд╛рджрди рдХреА рддреБрд▓рдирд╛ рдмреЗрд╣рддрд░ рдврдВрдЧ рд╕реЗ рдХрд┐рдП рдЧрдП рдЕрдиреБрдХреВрд▓рди рдХреЛ рджрд┐рдЦрд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВ, рдХрд╛рд░реНрдп рдЕрд╡рдзрд┐ рд╕реЗ рдЪрд╛рд░ рдЕрд╡рдзрд┐ рдХреЗ рд▓рд┐рдП рдПрдХ рдХрд╛рд░реНрдп рд╕рдордп рдмрдирд╛рдиреЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рдЦрд░реНрдЪ рд╣реЛрддрд╛ рд╣реИред


рдореБрдЭреЗ рд▓рдЧрднрдЧ 3 рд╣рдЬрд╛рд░ рдкреАрд░рд┐рдпрдб рд▓рдЧреЗред рдореИрдВ EXPLAIN рдореЗрдВ рдХреЗрд╡рд▓ рд╢реАрд░реНрд╖ рд╕рд╛рд░рд╛рдВрд╢ рдкрдВрдХреНрддрд┐ рджреВрдВрдЧрд╛, рд╡рд┐рд╢рд┐рд╖реНрдЯ рдорд╛рди рдЗрд╕ рдкреНрд░рдХрд╛рд░ рд╣реИрдВред


рдореВрд▓ рд╡рд┐рдХрд▓реНрдк:


 GroupAggregate (cost=265790.95..296098.23 rows=144320 width=36) (actual time=656.654..894.383 rows=2898 loops=1) ... 

рдЕрдиреБрдХреВрд▓рд┐рдд:


 Hash Join (cost=45.01..127.52 rows=70 width=36) (actual time=1.620..5.385 rows=2898 loops=1) ... 

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


рд╕рдм рдХреБрдЫ рдареАрдХ рд▓рдЧ рд░рд╣рд╛ рдерд╛, рд▓реЗрдХрд┐рди рдХреНрдпреЛрдВ, рдЗрд╕ рддрд░рд╣ рдХрд╛ рдЕрдиреБрдХреВрд▓рди рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж, рдореИрдВрдиреЗ рдЦреБрдж рдХреЗ рд▓рд┐рдП рдЕрдиреБрд░реЛрдз рдХрд╛ рдкрд╣рд▓рд╛ рд╕рдВрд╕реНрдХрд░рдг рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрдм рддрдХ рдХрд┐ рдЗрд╕рдХрд╛ рдкреНрд░рджрд░реНрд╢рди рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рдерд╛? рд╣рд╛рдВ, рдХреНрдпреЛрдВрдХрд┐ рдЕрдиреБрдХреВрд▓рд┐рдд рд╕рдВрд╕реНрдХрд░рдг рдирд┐рд╕реНрд╕рдВрджреЗрд╣ рддреЗрдЬ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХ рд╕рдордп рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд рдкрдардиреАрдпрддрд╛ рдЦрд░рд╛рдм рд╣реЛ рдЧрдИ рд╣реИред рдпрд╣реА рд╣реИ, рдЕрдЧрд▓реА рдмрд╛рд░ рдЬрдм рдореБрдЭреЗ рдЕрдкрдиреА рдмрджрд▓реА рд╣реБрдИ рд╢рд░реНрддреЛрдВ рдХреЗ рддрд╣рдд рдЕрдиреБрд░реЛрдз рдХреЛ рдлрд┐рд░ рд╕реЗ рд▓рд┐рдЦрдирд╛ рд╣реЛрдЧрд╛, рддреЛ рдореБрдЭреЗ (рдпрд╛ рдореБрдЭреЗ рдирд╣реАрдВ) рдпрд╣ рд╕рдордЭрдиреЗ рдореЗрдВ рдЕрдзрд┐рдХ рд╕рдордп рдмрд┐рддрд╛рдирд╛ рд╣реЛрдЧрд╛ рдХрд┐ рдЕрдиреБрд░реЛрдз рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред


рдЖрдЬ рдХреЗ рд▓рд┐рдП рдмрд╕ рдЗрддрдирд╛ рд╣реА, рдЯреЗрдВрдЯрд▓реЗрд╕ рдХреЛ рдЧрд░реНрдо рд░рдЦреЛ, рдФрд░ рдореИрдВ рдЕрдЧрд▓реЗ рд░реЗрдбрд┐рдпреЛ рдПрд╕рдХреНрдпреВрдПрд▓ рд░рд┐рд▓реАрдЬ рд╣реЛрдиреЗ рддрдХ рдЖрдкрдХреЛ рдЕрд▓рд╡рд┐рджрд╛ рдХрд╣реВрдВрдЧрд╛ред

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


All Articles