рд╕рд░реНрд╡рд╢реНрд░реЗрд╖реНрда рдПрд╕рдХреНрдпреВрдПрд▓ рдордзреНрдпрдо рдХрдард┐рдирд╛рдИ рд╡рд╛рд▓реЗ рдкреНрд░рд╢реНрди

SQL рдкрд╛рдареНрдпрдХреНрд░рдо рдХрд╛ рдкрд╣рд▓рд╛ 70% рдмрд╣реБрдд рд╕реАрдзрд╛ рд▓рдЧрддрд╛ рд╣реИред рд╢реЗрд╖ 30% рдкрд░ рдХрдард┐рдирд╛рдЗрдпрд╛рдБ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИрдВред

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

рд╢реБрд░реБрдЖрддреА рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдХрдИ рд╢рд╛рдирджрд╛рд░ рдПрд╕рдХреНрдпреВрдПрд▓ рдЯреНрдпреВрдЯреЛрд░рд┐рдпрд▓ рд╣реИрдВред рдореЗрд░реЗ рдкрд╕рдВрджреАрджрд╛ рд╣реИрдВрдХреЛрдбреЗрдХреЗрдбрдореА рдХреЗ рдЗрдВрдЯрд░рдПрдХреНрдЯрд┐рд╡ рдПрд╕рдХреНрдпреВрдПрд▓ рдФрд░ рдЬрд┐ рдЪреБрдВрдЧ рдХрд╛рдУ рджреНрд╡рд╛рд░рд╛ рд╕реНрдЯрд╛рд░ рдПрд╕рдХреНрдпреВрдПрд▓ рдкрд╛рдареНрдпрдХреНрд░рдореЛрдВ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ ред рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдПрд╕рдХреНрдпреВрдПрд▓ рдкрд╛рдареНрдпрдХреНрд░рдо рдХрд╛ рдкрд╣рд▓рд╛ 70% рдХрд╛рдлреА рд╕рд░рд▓ рд╣реИ, рдФрд░ рдЕрд╕рд▓реА рдореБрд╢реНрдХрд┐рд▓реЗрдВ рд╢реЗрд╖ 30% рдореЗрдВ рд╢реБрд░реВ рд╣реЛрддреА рд╣реИрдВ, рдЬреЛ рд╢реБрд░реБрдЖрддреА рдЧрд╛рдЗрдбреЛрдВ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХреА рдХрдВрдкрдирд┐рдпреЛрдВ рдореЗрдВ рдбреЗрдЯрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдХреЛрдВ рдФрд░ рдбреЗрдЯрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╡рд┐рд╢реЗрд╖рдЬреНрдЮреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдореЗрдВ рдЕрдХреНрд╕рд░ рдЗрди 30% рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдкреНрд░рд╢реНрди рдкреВрдЫреЗ рдЬрд╛рддреЗ рд╣реИрдВред

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

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

рд╕рд╛рдордЧреНрд░реА



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

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

рдорд╛рди рд▓рд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ рдФрд░ рдореИрдиреБрдЕрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВ


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

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

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

рдПрд╕рдХреНрдпреВрдПрд▓ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдореЗрдВ рдЬрдЯрд┐рд▓ рдХрд╛рд░реНрдпреЛрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЯрд┐рдкреНрд╕


рд╕рдмрд╕реЗ рдкрд╣рд▓реЗ, рд╕рднреА рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдХреЗ рд▓рд┐рдП рдорд╛рдирдХ рд╕реБрдЭрд╛рд╡ ...

  1. рд╕рдорд╕реНрдпрд╛ рдХреЗ рд╡рд░реНрдгрди рдХреЛ рдзреНрдпрд╛рди рд╕реЗ рд╕реБрдиреЗрдВ, рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░рдХрд░реНрддрд╛ рдХреЛ рд╕рдорд╕реНрдпрд╛ рдХрд╛ рд╕рд╛рд░ рджреЛрд╣рд░рд╛рдПрдВ
  2. рдПрдХ рдмреЙрд░реНрдбрд░рд▓рд╛рдЗрди рдорд╛рдорд▓реЗ рдХреЛ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░реЗрдВ рдХрд┐ рдЖрдк рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╕рдордЭрддреЗ рд╣реИрдВ (рдпрд╛рдиреА, рдПрдХ рдкрдВрдХреНрддрд┐ рдЬрд┐рд╕реЗ рдЕрдВрддрд┐рдо SQL рдХреНрд╡реЗрд░реА рдореЗрдВ рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ рдЬрд┐рд╕реЗ рдЖрдк рд▓рд┐рдЦрдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ)
  3. ( ) , тАФ : ,
    • , ,
  4. SQL, , . , .


рдпрд╣рд╛рдБ рд╕реВрдЪреАрдмрджреНрдз рдХреБрдЫ рдореБрджреНрджреЛрдВ рдХреЛ рдкреБрд░рд╛рдиреЗ рдкреЗрд░рд┐рд╕реНрдХреЛрдк рдмреНрд▓реЙрдЧ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпреЛрдВ (рдЬреНрдпрд╛рджрд╛рддрд░ рд╢реЙрди рдХреБрдХ рджреНрд╡рд╛рд░рд╛ 2014 рдХреЗ рдЖрд╕рдкрд╛рд╕ рд▓рд┐рдЦрд╛ рдЧрдпрд╛ рд╣реИ, рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ , рд╣рд╛рд▓рд╛рдВрдХрд┐ рдЙрдирдХрд╛ рд▓реЗрдЦрдХ SiSense рдкреЗрд░рд┐рд╕реНрдХреЛрдк рдХреЗ рд╕рд╛рде рд╡рд┐рд▓рдп рдХреЗ рдмрд╛рдж рд╕рд╛рдордЧреНрд░реА рд╕реЗ рд╣рдЯрд╛ рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ), рд╕рд╛рде рд╣реА рд╕рд╛рде StOOverflow рдкрд░ рдЪрд░реНрдЪрд╛ рд╕реЗред рдпрджрд┐ рдЖрд╡рд╢реНрдпрдХ рд╣реЛ, рддреЛ рдкреНрд░рддреНрдпреЗрдХ рдкреНрд░рд╢реНрди рдХреА рд╢реБрд░реБрдЖрдд рдореЗрдВ рд╕реНрд░реЛрддреЛрдВ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред

рдкрд░ рдЪрдпрди рд╕реНрдЯрд╛рд░ рдПрд╕рдХреНрдпреВрдПрд▓ рднреА рдПрдХ рдЕрдЪреНрдЫрд╛ рд╣реИ brainteasers рдХрд╛ рдЪрдпрди , рдЗрд╕ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдХрд╛ рдкреВрд░рдХ рдореБрджреНрджреЛрдВред

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдпреЗ рдкреНрд░рд╢реНрди рдореЗрд░реЗ рд╕реНрд╡рдпрдВ рдХреЗ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рд╕реЗ рдкреНрд░рд╢реНрдиреЛрдВ рдХреА рд╢рд╛рдмреНрджрд┐рдХ рдкреНрд░рддрд┐рдпрд╛рдВ рдирд╣реАрдВ рд╣реИрдВ, рдФрд░ рдЙрдирдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрди рдХрдВрдкрдирд┐рдпреЛрдВ рдореЗрдВ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬрд┐рдирдореЗрдВ рдореИрдВрдиреЗ рдХрд╛рдо рдХрд┐рдпрд╛ рдерд╛ рдпрд╛ рдХрд╛рдо рдХрд┐рдпрд╛ рдерд╛ред

рд╕реНрд╡-рд╕рдВрдШ рдХрд╛рд░реНрдп


рдирдВрдмрд░ 1. рдкреНрд░рддрд┐рд╢рдд рдорд╣реАрдиреЗ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди


рд╕рдВрджрд░реНрдн: рдпрд╣ рдЬрд╛рдирдирд╛ рдЕрдХреНрд╕рд░ рдЙрдкрдпреЛрдЧреА рд╣реЛрддрд╛ рд╣реИ рдХрд┐ рдПрдХ рдкреНрд░рдореБрдЦ рдореАрдЯреНрд░рд┐рдХ рдХреИрд╕реЗ рдмрджрд▓рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдорд╣реАрдиреЗ рд╕реЗ рдорд╣реАрдиреЗ рддрдХ рд╕рдХреНрд░рд┐рдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдорд╛рд╕рд┐рдХ рджрд░реНрд╢рдХред рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ loginsрдЗрд╕ рд░реВрдк рдореЗрдВ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ:

| user_id | рддрд╛рд░реАрдЦ |
| --------- | ------------ |
| 1 | 2018-07-01 |
| 234 | 2018-07-02 |
| 3 | 2018-07-02 |
| 1 | 2018-07-02 |
| ... | ... |
| 234 | 2018-10-04 |

рдЙрджреНрджреЗрд╢реНрдп : рд╕рдХреНрд░рд┐рдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ (MAU) рдХреЗ рдорд╛рд╕рд┐рдХ рд╢реНрд░реЛрддрд╛рдУрдВ рдореЗрдВ рдорд╛рд╕рд┐рдХ рдкреНрд░рддрд┐рд╢рдд рдкрд░рд┐рд╡рд░реНрддрди рджреЗрдЦреЗрдВред

рд╕рдорд╛рдзрд╛рди:
(рдЗрд╕ рджрд╕реНрддрд╛рд╡реЗрдЬрд╝ рдореЗрдВ рдХреЛрдб рдХреЗ рдЕрдиреНрдп рдмреНрд▓реЙрдХреЛрдВ рдХреА рддрд░рд╣ рдпрд╣ рд╕рдорд╛рдзрд╛рди, SQL рд╕рд┐рдВрдЯреИрдХреНрд╕ рддрддреНрд╡реЛрдВ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЯрд┐рдкреНрдкрдгреА рдХрд░рддрд╛ рд╣реИ рдЬреЛ рд╡рд┐рднрд┐рдиреНрди SQL рд╡реЗрд░рд┐рдПрдВрдЯ рдФрд░ рдЕрдиреНрдп рдиреЛрдЯреЛрдВ рдХреЗ рдмреАрдЪ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ)

WITH mau AS 
(
  SELECT 
   /* 
    *       
    *  , . .   ,    . 
    *    ,   
    *
    *  Postgres  DATE_TRUNC(),   
    *      SQL   
    * . https://www.postgresql.org/docs/9.0/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
    */ 
    DATE_TRUNC('month', date) month_timestamp,
    COUNT(DISTINCT user_id) mau
  FROM 
    logins 
  GROUP BY 
    DATE_TRUNC('month', date)
  )
 
 SELECT 
    /*
    *    SELECT      . 
    * 
    *        ,   
    *    ,   , 
    *        ..
    */ 
    a.month_timestamp previous_month, 
    a.mau previous_mau, 
    b.month_timestamp current_month, 
    b.mau current_mau, 
    ROUND(100.0*(b.mau - a.mau)/a.mau,2) AS percent_change 
 FROM
    mau a 
 JOIN 
    /*
    *   `ON b.month_timestamp = a.month_timestamp + interval '1 month'` 
    */
    mau b ON a.month_timestamp = b.month_timestamp - interval '1 month' 

рдирдВрдмрд░ 2. рдкреЗрдбрд╝ рдХреА рд╕рдВрд░рдЪрдирд╛ рдХреЛ рдЪрд┐рд╣реНрдирд┐рдд рдХрд░рдирд╛


рд╕рдВрджрд░реНрдн: рдорд╛рди рд▓реЗрдВ рдХрд┐ рдЖрдкрдХреЗ рдкрд╛рд╕ treeрджреЛ рд╕реНрддрдВрднреЛрдВ рд╡рд╛рд▓реА рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ : рдкрд╣рд▓рд╛ рдиреЛрдбреНрд╕ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ, рдФрд░ рджреВрд╕рд░рд╛ рдореВрд▓ рдиреЛрдбреНрд╕ред

рдиреЛрдб рдЕрднрд┐рднрд╛рд╡рдХ
12
реи рел
рей рел
рек рей
рел рдирд▓ 

рдЯрд╛рд╕реНрдХ: рдПрд╕рдХреНрдпреВрдПрд▓ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рд▓рд┐рдЦреЗрдВ рдХрд┐ рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдиреЛрдб рдХреЛ рдЖрдВрддрд░рд┐рдХ, рдореВрд▓, рдпрд╛ рдкрддреНрддреА рдпрд╛ рдкрддреНрддреА рдХреЗ рд░реВрдк рдореЗрдВ рдирд╛рдорд┐рдд рдХрд░реЗрдВ, рддрд╛рдХрд┐ рдЙрдкрд░реЛрдХреНрдд рдореВрд▓реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд┐рд▓реЗрдВ:

node    label  
1       Leaf
2       Inner
3       Inner
4       Leaf
5       Root

(рдиреЛрдЯ: рдкреЗрдбрд╝ рдХреА рддрд░рд╣ рдбреЗрдЯрд╛ рд╕рдВрд░рдЪрдирд╛ рдХреА рд╢рдмреНрджрд╛рд╡рд▓реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЕрдзрд┐рдХ рдЬрд╛рдирдХрд╛рд░реА рдпрд╣рд╛рдВ рдкрд╛рдИ рдЬрд╛ рд╕рдХрддреА рд╣реИ ред рд╣рд╛рд▓рд╛рдВрдХрд┐, рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ!)

рд╕рдорд╛рдзрд╛рди:
рдЖрднрд╛рд░: рдлреИрдмрд┐рдпрди рд╣реЙрдлрдореИрди рдиреЗ 2 рдордИ, 2020 рдХреЛ рдЗрд╕ рдЕрдзрд┐рдХ рд╕рд╛рдорд╛рдиреНрдпреАрдХреГрдд рд╕рдорд╛рдзрд╛рди рдХрд╛ рдкреНрд░рд╕реНрддрд╛рд╡ рджрд┐рдпрд╛ред рдлреЗрдмрд┐рдпрди рдХреЛ рдзрдиреНрдпрд╡рд╛рдж

WITH join_table AS
(
    SELECT 
        cur.node, 
        cur.parent, 
        COUNT(next.node) AS num_children
    FROM 
        tree cur
    LEFT JOIN 
        tree next ON (next.parent = cur.node)
    GROUP BY 
        cur.node, 
        cur.parent
)

SELECT
    node,
    CASE
        WHEN parent IS NULL THEN "Root"
        WHEN num_children = 0 THEN "Leaf"
        ELSE "Inner"
    END AS label
FROM 
    join_table 

рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдорд╛рдзрд╛рди, рд╕реНрдкрд╖реНрдЯ рдХрдиреЗрдХреНрд╢рди рдХреЗ рдмрд┐рдирд╛:

рдкрд╛рд╡рддреА: 2 рдордИ рдХреЛ рд╡рд┐рд▓рд┐рдпрдо Chardgin, 2020 рд╣рд╛рд▓рдд рдХреЗ рд▓рд┐рдП рдХреА рдЬрд░реВрд░рдд рдХреА рдУрд░ рдзреНрдпрд╛рди рдЖрдХрд░реНрд╖рд┐рдд WHERE parent IS NOT NULLрдХрд┐ рдЗрд╕ рд╕рдорд╛рдзрд╛рди рд╡рд╛рдкрд╕реА LeafрдмрдЬрд╛рдп NULLред рдзрдиреНрдпрд╡рд╛рдж рд╡рд┐рд▓рд┐рдпрдо!

SELECT 
    node,
    CASE 
        WHEN parent IS NULL THEN 'Root'
        WHEN node NOT IN 
            (SELECT parent FROM tree WHERE parent IS NOT NULL) THEN 'Leaf'
        WHEN node IN (SELECT parent FROM tree) AND parent IS NOT NULL THEN 'Inner'
    END AS label 
 from 
    tree

рдирдВрдмрд░ 3. рдкреНрд░рддрд┐ рдорд╛рд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рддрд┐рдзрд╛рд░рдг (рдХрдИ рднрд╛рдЧреЛрдВ)


рдЖрднрд╛рд░: рдЗрд╕ рдХрд╛рд░реНрдп рдХреЛ SiSense рдмреНрд▓реЙрдЧ рд▓реЗрдЦ рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛, "рдкреНрд░рддрд┐рдзрд╛рд░рдг, рдмрд╣рд┐рд░реНрд╡рд╛рд╣ рдФрд░ рдкреБрдирд░реНрд╕рдХреНрд░рд┐рдпрди рдХреА рдЧрдгрдирд╛ рдХреЗ рд▓рд┐рдП рд╕реНрд╡-рд╕рдВрдШреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ ред "

рднрд╛рдЧ 1


рд╕рдВрджрд░реНрдн: рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рдХрд┐рд╕реА рд╕рд╛рдЗрдЯ рдкрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рд╛рдзрд┐рдХрд░рдг рдХреЗ рдЖрдВрдХрдбрд╝реЗ рд╣реИрдВ logins:

| user_id | рддрд╛рд░реАрдЦ |
| --------- | ------------ |
| 1 | 2018-07-01 |
| 234 | 2018-07-02 |
| 3 | 2018-07-02 |
| 1 | 2018-07-02 |
| ... | ... |
| 234 | 2018-10-04 |

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

рдлреЗрд╕рд▓рд╛:

SELECT 
    DATE_TRUNC('month', a.date) month_timestamp, 
    COUNT(DISTINCT a.user_id) retained_users 
 FROM 
    logins a 
 JOIN 
    logins b ON a.user_id = b.user_id 
        AND DATE_TRUNC('month', a.date) = DATE_TRUNC('month', b.date) + 
                                             interval '1 month'
 GROUP BY 
    date_trunc('month', a.date)

рдЖрднрд╛рд░:
рдЯреЙрдо рдореЙрд░реНрдЯреЗрд▓ рдиреЗ рдмрддрд╛рдпрд╛ рдХрд┐ рд╕реНрд╡-рдЬреБрдбрд╝рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ user_id рдХреЛ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рд╕рдорд╛рдзрд╛рди рдХреЛ рдФрд░ рдЕрдзрд┐рдХ рдХреБрд╢рд▓ рдмрдирд╛рддрд╛ рд╣реИ, рдФрд░ рдиреАрдЪреЗ рджрд┐рдП рдЧрдП рдХреЛрдб рдХрд╛ рд╕реБрдЭрд╛рд╡ рджрд┐рдпрд╛ рд╣реИред рдзрдиреНрдпрд╡рд╛рдж рдЯреЙрдо!

рджреВрд╕рд░рд╛ рддрд░реАрдХрд╛:

WITH DistinctMonthlyUsers AS (
  /*
  *     ** , 
  *  
  */
    SELECT DISTINCT
      DATE_TRUNC('MONTH', a.date) AS month_timestamp,
      user_id
    FROM logins
  )

SELECT
  CurrentMonth.month_timestamp month_timestamp,
  COUNT(PriorMonth.user_id) AS retained_user_count
FROM 
    DistinctMonthlyUsers AS CurrentMonth
LEFT JOIN 
    DistinctMonthlyUsers AS PriorMonth
  ON
    CurrentMonth.month_timestamp = PriorMonth.month_timestamp + INTERVAL '1 MONTH'
    AND 
    CurrentMonth.user_id = PriorMonth.user_id

рднрд╛рдЧ 2


рдХрд╛рд░реНрдп: рдЕрдм рд╣рдо рдкреНрд░рддрд┐ рдорд╛рд╣ рдмрдирд╛рдП рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд╛ рдкрд┐рдЫрд▓рд╛ рдХрд╛рд░реНрдп рд▓реЗрддреЗ рд╣реИрдВ - рдФрд░ рдЗрд╕реЗ рдЙрд▓реНрдЯрд╛ рдХрд░рддреЗ рд╣реИрдВред рд╣рдо рдЙрди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЧрд┐рдирдиреЗ рдХрд╛ рдЕрдиреБрд░реЛрдз рд▓рд┐рдЦреЗрдВрдЧреЗ рдЬреЛ рдЗрд╕ рдорд╣реАрдиреЗ рд╕рд╛рдЗрдЯ рдкрд░ рдирд╣реАрдВ рд▓реМрдЯреЗ рд╣реИрдВред рдпрд╣реА рд╣реИ, "рдЦреЛ" рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ред

рдлреЗрд╕рд▓рд╛:

SELECT 
    DATE_TRUNC('month', a.date) month_timestamp, 
    COUNT(DISTINCT b.user_id) churned_users 
FROM 
    logins a 
FULL OUTER JOIN 
    logins b ON a.user_id = b.user_id 
        AND DATE_TRUNC('month', a.date) = DATE_TRUNC('month', b.date) + 
                                         interval '1 month'
WHERE 
    a.user_id IS NULL 
GROUP BY 
    DATE_TRUNC('month', a.date)

рдХреГрдкрдпрд╛ рдзреНрдпрд╛рди рджреЗрдВ рдХрд┐ рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЛ рднреА рд╕рд╛рде рд╣рд▓ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ LEFTрдпрд╛ RIGHTред

рднрд╛рдЧ рей


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

рд╕рдВрджрд░реНрдн : рддреЛ рд╣рдордиреЗ рдкрд┐рдЫрд▓реА рджреЛ рд╕рдорд╕реНрдпрд╛рдУрдВ рдХрд╛ рдЕрдЪреНрдЫрд╛ рдХрд╛рдо рдХрд┐рдпрд╛ред рдирдП рдХрд╛рд░реНрдп рдХреА рд╢рд░реНрддреЛрдВ рдХреЗ рддрд╣рдд, рдЕрдм рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдЦреЛрдП рд╣реБрдП рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреА рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ user_churnsред рдпрджрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрд┐рдЫрд▓реЗ рдорд╣реАрдиреЗ рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдерд╛, рд▓реЗрдХрд┐рди рдлрд┐рд░ рдЗрд╕рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдирд╣реАрдВ рд╣реИ, рддреЛ рдЙрд╕реЗ рдЗрд╕ рдорд╣реАрдиреЗ рдХреЗ рд▓рд┐рдП рддрд╛рд▓рд┐рдХрд╛ рдореЗрдВ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдпрд╣рд╛рдБ рдпрд╣ рдХреИрд╕рд╛ рджрд┐рдЦрддрд╛ рд╣реИ user_churns:

| user_id | month_date |
| --------- | ------------ |
| 1 | 2018-05-01 |
| 234 | 2018-05-01 |
| 3 | 2018-05-01 |
| 12 | 2018-05-01 |
| ... | ... |
| 234 | 2018-10-01 |

рдЯрд╛рд╕реНрдХ : рдЕрдм рдЖрдк рдХреЛрд╣реЙрд░реНрдЯ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рдЬреЛ рдХрд┐ рд╕рдХреНрд░рд┐рдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреА рд╕рдордЧреНрд░рддрд╛ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рд╣реИ, рдЬрд┐рдиреНрд╣реЗрдВ рдЕрддреАрдд рдореЗрдВ рдкреБрди: рд╕рдХреНрд░рд┐рдп рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ ред рдЗрди рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд╕рд╛рде рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдмрдирд╛рдПрдВред рдЖрдк рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ user_churnsрдФрд░ рдПрдХ рдкрд▓рдЯрди рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ loginsред Postgres рдореЗрдВ, рд╡рд░реНрддрдорд╛рди рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рдкрд╣реБрдБрдЪрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ current_timestampред

рдлреЗрд╕рд▓рд╛:

WITH user_login_data AS 
(
    SELECT 
        DATE_TRUNC('month', a.date) month_timestamp,
        a.user_id,
        /* 
        *   ,    SQL,   , 
        *      SELECT   HAVING.
        *       .  
        */ 
        MAX(b.month_date) as most_recent_churn, 
        MAX(DATE_TRUNC('month', c.date)) as most_recent_active 
     FROM 
        logins a
     JOIN 
        user_churns b 
            ON a.user_id = b.user_id AND DATE_TRUNC('month', a.date) > b.month_date 
     JOIN
        logins c 
            ON a.user_id = c.user_id 
            AND 
            DATE_TRUNC('month', a.date) > DATE_TRUNC('month', c.date)
     WHERE 
        DATE_TRUNC('month', a.date) = DATE_TRUNC('month', current_timestamp)
     GROUP BY 
        DATE_TRUNC('month', a.date),
        a.user_id
     HAVING 
        most_recent_churn > most_recent_active

рдирдВрдмрд░ 4. рдХреБрд▓ рдмрдврд╝рд╛рдирд╛


рдЖрднрд╛рд░: рдпрд╣ рдХрд╛рд░реНрдп SiSense рдмреНрд▓реЙрдЧ рд▓реЗрдЦ , SQL рдореЗрдВ рдХреИрд╢ рдлрд╝реНрд▓реЛ рдореЙрдбрд▓рд┐рдВрдЧ рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ ред

рд╕рдВрджрд░реНрдн: рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ transactionsрдЗрд╕ рд░реВрдк рдореЗрдВ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ:

| рддрд╛рд░реАрдЦ | рдХреИрд╢_рдлреНрд▓реЛ |
| ------------ | ----------- |
| 2018-01-01 | -1000 |
| 2018-01-02 | -100 |
| 2018-01-03 | 50 |
| ... | ... |

cash_flowрдкреНрд░рддреНрдпреЗрдХ рджрд┐рди рдХреЗ рд▓рд┐рдП рд░рд╛рдЬрд╕реНрд╡ рдорд╛рдЗрдирд╕ рдХрд╣рд╛рдБ рд╣реИред

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

| рддрд╛рд░реАрдЦ | рд╕рдВрдЪрдпреА_cf |
| ------------ | --------------- |
| 2018-01-01 | -1000 |
| 2018-01-02 | -1100 |
| 2018-01-03 | -1050 |
| ... | ... |

рдлреЗрд╕рд▓рд╛:

SELECT 
    a.date date, 
    SUM(b.cash_flow) as cumulative_cf 
FROM
    transactions a
JOIN b 
    transactions b ON a.date >= b.date 
GROUP BY 
    a.date 
ORDER BY 
    date ASC

рдПрдХ рд╡рд┐рдВрдбреЛ рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдорд╛рдзрд╛рди (рдЕрдзрд┐рдХ рдХреБрд╢рд▓!):

SELECT 
    date, 
    SUM(cash_flow) OVER (ORDER BY date ASC) as cumulative_cf 
FROM
    transactions 
ORDER BY 
    date ASC

рдирдВрдмрд░ 5. рдореВрд╡рд┐рдВрдЧ рдПрд╡рд░реЗрдЬ


рдЖрднрд╛рд░: рдпрд╣ рдХрд╛рд░реНрдп MySQL рдФрд░ SQL рд╕рд░реНрд╡рд░ рдореЗрдВ рдЪрд▓ рд░рд╣рд╛ рд╣реИ, SiSense рдмреНрд▓реЙрдЧ рд▓реЗрдЦ рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рд╣реИ ред

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

рд╕рдВрджрд░реНрдн : рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ signupsрдЗрд╕ рд░реВрдк рдореЗрдВ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ:

| рддрд╛рд░реАрдЦ | sign_ups |
| ------------ | ---------- |
| 2018-01-01 | 10 |
| 2018-01-02 | 20 |
| 2018-01-03 | 50 |
| ... | ... |
| 2018-10-01 | 35 |

рдХрд╛рд░реНрдп : рджреИрдирд┐рдХ рдкрдВрдЬреАрдХрд░рдгреЛрдВ рдХреЗ 7-рджрд┐рд╡рд╕реАрдп рдЪрд▓рддреА рдФрд╕рдд рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреБрд░реЛрдз рд▓рд┐рдЦреЗрдВред

рдлреЗрд╕рд▓рд╛:

SELECT 
  a.date, 
  AVG(b.sign_ups) average_sign_ups 
FROM 
  signups a 
JOIN 
  signups b ON a.date <= b.date + interval '6 days' AND a.date >= b.date
GROUP BY 
  a.date

рдирдВрдмрд░ 6. рдХрдИ рдХрдиреЗрдХреНрд╢рди рдХреА рд╕реНрдерд┐рддрд┐


рдЖрднрд╛рд░: рдпрд╣ рдХрд╛рд░реНрдп SiSense рдмреНрд▓реЙрдЧ рд▓реЗрдЦ, "SQL рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рдЕрдкрдиреЗ рдИрдореЗрд▓ рдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг" рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рд╣реИ ред

рд╕рдВрджрд░реНрдн: рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реА рддрд╛рд▓рд┐рдХрд╛ emailsрдореЗрдВ рдкрддреЗ рд╕реЗ рднреЗрдЬреЗ рдЧрдП рдИрдореЗрд▓ рд╣реИрдВ zach@g.comрдФрд░ рдЙрд╕ рдкрд░ рдкреНрд░рд╛рдкреНрдд рд╣реБрдП рд╣реИрдВ:

| рдЖрдИрдбреА | рд╡рд┐рд╖рдп | рд╕реЗ | рдХреЛ | рдЯрд╛рдЗрдорд╕реНрдЯреИрдореНрдк |
| ---- | ---------- | ------------------ | -------------- | ------------------ |
| 1 | рдпреЛрд╕реЗрдорд╛рдЗрдЯ | zach@g.com | thomas@g.com | 2018-01-02 12:45:03 |
| 2 | рдмрдбрд╝рд╛ рд╕реБрд░ | sarah@g.com | thomas@g.com | 2018-01-02 16:30:01 |
| 3 | рдпреЛрд╕реЗрдорд╛рдЗрдЯ | thomas@g.com | zach@g.com | 2018-01-02 16:35:04 |
| 4 | рдЪрд▓ рд░рд╣рд╛ рд╣реИ | jill@g.com | zach@g.com | 2018-01-03 08:12:45 |
| 5 | рдпреЛрд╕реЗрдорд╛рдЗрдЯ | zach@g.com | thomas@g.com | 2018-01-03 14:02:01 |
| 6 | рдпреЛрд╕реЗрдорд╛рдЗрдЯ | thomas@g.com | zach@g.com | 2018-01-03 15:01:05 |
| .. | .. | .. | .. | .. |

рдХрд╛рд░реНрдп:id рднреЗрдЬреЗ рдЧрдП рдкреНрд░рддреНрдпреЗрдХ рдЕрдХреНрд╖рд░ ( ) рдХреЗ рд▓рд┐рдП рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╕рдордп рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдЕрдиреБрд░реЛрдз рд▓рд┐рдЦреЗрдВ zach@g.comред рдЕрдиреНрдп рдкрддреЛрдВ рдкрд░ рдкрддреНрд░ рд╢рд╛рдорд┐рд▓ рди рдХрд░реЗрдВред рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдкреНрд░рддреНрдпреЗрдХ рдзрд╛рдЧреЗ рдХрд╛ рдПрдХ рдЕрдиреВрдард╛ рд╡рд┐рд╖рдп рд╣реИред рдзреНрдпрд╛рди рд░рдЦреЗрдВ рдХрд┐ рдзрд╛рдЧреЗ рдореЗрдВ zach@g.comрдФрд░ рдЕрдиреНрдп рдкреНрд░рд╛рдкреНрддрдХрд░реНрддрд╛рдУрдВ рдХреЗ рдмреАрдЪ рдХрдИ рджреМрд░-рдпрд╛рддреНрд░рд╛ рдкрддреНрд░ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ ред

рдлреЗрд╕рд▓рд╛:

SELECT 
    a.id, 
    MIN(b.timestamp) - a.timestamp as time_to_respond 
FROM 
    emails a 
JOIN
    emails b 
        ON 
            b.subject = a.subject 
        AND 
            a.to = b.from
        AND 
            a.from = b.to 
        AND 
            a.timestamp < b.timestamp 
 WHERE 
    a.to = 'zach@g.com' 
 GROUP BY 
    a.id 

рд╡рд┐рдВрдбреЛ рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп


рдирдВрдмрд░ 1. рдЕрдзрд┐рдХрддрдо рдорд╛рди рд╡рд╛рд▓реЗ рдкрд╣рдЪрд╛рдирдХрд░реНрддрд╛ рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдПрдВ


рд╕рдВрджрд░реНрдн: рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ salariesрдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рд╡рд┐рднрд╛рдЧреЛрдВ рдФрд░ рдХрд░реНрдордЪрд╛рд░рд┐рдпреЛрдВ рдХреЗ рд╡реЗрддрди рдкрд░ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ :

  depname | рдПрдореНрдкрдиреЛ | рд╡реЗрддрди |     
----------- + ------- + -------- +
 рд╡рд┐рдХрд╛рд╕ | 11 | 5200 |
 рд╡рд┐рдХрд╛рд╕ | 7 | 4200 |
 рд╡рд┐рдХрд╛рд╕ | 9 | 4500 |
 рд╡рд┐рдХрд╛рд╕ | 8 | 6000 |
 рд╡рд┐рдХрд╛рд╕ | 10 | 5200 |
 рдХрд╛рд░реНрдорд┐рдХ | 5 | 3500 |
 рдХрд╛рд░реНрдорд┐рдХ | 2 | 3900 |
 рдмрд┐рдХреНрд░реА | 3 | 4800 |
 рдмрд┐рдХреНрд░реА | 1 | 5000 |
 рдмрд┐рдХреНрд░реА | 4 | 4800 |

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

рдлреЗрд╕рд▓рд╛:

WITH max_salary AS (
    SELECT 
        MAX(salary) max_salary
    FROM 
        salaries
    )
SELECT 
    s.empno
FROM 
    salaries s
JOIN 
    max_salary ms ON s.salary = ms.max_salary

рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдорд╛рдзрд╛рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ RANK():

WITH sal_rank AS 
  (SELECT 
    empno, 
    RANK() OVER(ORDER BY salary DESC) rnk
  FROM 
    salaries)
SELECT 
  empno
FROM
  sal_rank
WHERE 
  rnk = 1;

рдирдВрдмрд░ 2. рд╡рд┐рдВрдбреЛ рдлрд╝рдВрдХреНрд╢рди рдХреЗ рд╕рд╛рде рдФрд╕рдд рдореВрд▓реНрдп рдФрд░ рд░реИрдВрдХрд┐рдВрдЧ (рдХрдИ рднрд╛рдЧ)


рднрд╛рдЧ 1


рд╕рдВрджрд░реНрдн : рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ salariesрдЗрд╕ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ:

  depname | рдПрдореНрдкрдиреЛ | рд╡реЗрддрди |     
----------- + ------- + -------- +
 рд╡рд┐рдХрд╛рд╕ | 11 | 5200 |
 рд╡рд┐рдХрд╛рд╕ | 7 | 4200 |
 рд╡рд┐рдХрд╛рд╕ | 9 | 4500 |
 рд╡рд┐рдХрд╛рд╕ | 8 | 6000 |
 рд╡рд┐рдХрд╛рд╕ | 10 | 5200 |
 рдХрд╛рд░реНрдорд┐рдХ | 5 | 3500 |
 рдХрд╛рд░реНрдорд┐рдХ | 2 | 3900 |
 рдмрд┐рдХреНрд░реА | 3 | 4800 |
 рдмрд┐рдХреНрд░реА | 1 | 5000 |
 рдмрд┐рдХреНрд░реА | 4 | 4800 |

рдХрд╛рд░реНрдп: рдПрдХ рдХреНрд╡реЗрд░реА рд▓рд┐рдЦреЗрдВ рдЬреЛ рдПрдХ рд╣реА рддрд╛рд▓рд┐рдХрд╛ рд▓реМрдЯрд╛рддреА рд╣реИ, рд▓реЗрдХрд┐рди рдПрдХ рдирдП рдХреЙрд▓рдо рдХреЗ рд╕рд╛рде рдЬреЛ рд╡рд┐рднрд╛рдЧ рдХреЗ рд▓рд┐рдП рдФрд╕рдд рд╡реЗрддрди рджрд┐рдЦрд╛рддрд╛ рд╣реИред рд╣рдо рдЗрд╕ рддрд░рд╣ рд╕реЗ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдХреА рдЙрдореНрдореАрдж рдХрд░реЗрдВрдЧреЗ:

  depname | рдПрдореНрдкрдиреЛ | рд╡реЗрддрди | avg_salary |     
----------- + ------- + -------- + ------------ +
 рд╡рд┐рдХрд╛рд╕ | 11 | 5200 | 5020 |
 рд╡рд┐рдХрд╛рд╕ | 7 | 4200 | 5020 |
 рд╡рд┐рдХрд╛рд╕ | 9 | 4500 | 5020 |
 рд╡рд┐рдХрд╛рд╕ | 8 | 6000 | 5020 |
 рд╡рд┐рдХрд╛рд╕ | 10 | 5200 | 5020 |
 рдХрд╛рд░реНрдорд┐рдХ | 5 | 3500 | 3700 |
 рдХрд╛рд░реНрдорд┐рдХ | 2 | 3900 | 3700 |
 рдмрд┐рдХреНрд░реА | 3 | 4800 | 4867 |
 рдмрд┐рдХреНрд░реА | 1 | 5000 | 4867 |
 рдмрд┐рдХреНрд░реА | 4 | 4800 | 4867 |

рдлреЗрд╕рд▓рд╛:

SELECT 
    *, 
    /*
    * AVG() is a Postgres command, but other SQL flavors like BigQuery use 
    * AVERAGE()
    */ 
    ROUND(AVG(salary),0) OVER (PARTITION BY depname) avg_salary
FROM
    salaries

рднрд╛рдЧ 2


рдХрд╛рд░реНрдп: рдПрдХ рдкреНрд░рд╢реНрди рд▓рд┐рдЦреЗрдВ рдЬреЛ рдЕрдкрдиреЗ рд╡рд┐рднрд╛рдЧ рдореЗрдВ рдЕрдкрдиреЗ рд╡реЗрддрди рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдЯрд╛рдЗрдо рд╢реАрдЯ рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рдХрд░реНрдордЪрд╛рд░реА рдХреА рд╕реНрдерд┐рддрд┐ рдХреЗ рд╕рд╛рде рдПрдХ рдХреЙрд▓рдо рдЬреЛрдбрд╝рддрд╛ рд╣реИ, рдЬрд╣рд╛рдВ рдЙрдЪреНрдЪрддрдо рд╡реЗрддрди рд╡рд╛рд▓реЗ рдХрд░реНрдордЪрд╛рд░реА рдХреЛ рд╕реНрдерд┐рддрд┐ рдорд┐рд▓рддреА рд╣реИред 1. рд╣рдо рдЗрд╕ рд░реВрдк рдореЗрдВ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдХреА рдЙрдореНрдореАрдж рдХрд░реЗрдВрдЧреЗ:

  depname | рдПрдореНрдкрдиреЛ | рд╡реЗрддрди | рд╕реИрд▓рд░реА_рдЯреНрд░реИрдХ |     
----------- + ------- + -------- + ------------- +
 рд╡рд┐рдХрд╛рд╕ | 11 | 5200 | 2 |
 рд╡рд┐рдХрд╛рд╕ | 7 | 4200 | 5 |
 рд╡рд┐рдХрд╛рд╕ | 9 | 4500 | 4 |
 рд╡рд┐рдХрд╛рд╕ | 8 | 6000 | 1 |
 рд╡рд┐рдХрд╛рд╕ | 10 | 5200 | 2 |
 рдХрд╛рд░реНрдорд┐рдХ | 5 | 3500 | 2 |
 рдХрд╛рд░реНрдорд┐рдХ | 2 | 3900 | 1 |
 рдмрд┐рдХреНрд░реА | 3 | 4800 | 2 |
 рдмрд┐рдХреНрд░реА | 1 | 5000 | 1 |
 рдмрд┐рдХреНрд░реА | 4 | 4800 | 2 |

рдлреЗрд╕рд▓рд╛:

SELECT 
    *, 
    RANK() OVER(PARTITION BY depname ORDER BY salary DESC) salary_rank
 FROM  
    salaries 

рдордзреНрдпрдо рдФрд░ рдЙрдЪреНрдЪ рдХрдард┐рдирд╛рдИ рдХреЗ рдЕрдиреНрдп рдХрд╛рд░реНрдп


рдирдВрдмрд░ 1. рд╣рд┐рд╕реНрдЯреЛрдЧреНрд░рд╛рдо


рд╕рдВрджрд░реНрдн: рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ sessionsрдЬрд╣рд╛рдВ рдкреНрд░рддреНрдпреЗрдХ рдкрдВрдХреНрддрд┐ рд╕реЗрдХрдВрдб рдореЗрдВ рд▓рдВрдмрд╛рдИ рдХреЗ рд╕рд╛рде рд╡реАрдбрд┐рдпреЛ рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рд╕рддреНрд░ рдХрд╛ рдкреНрд░рддрд┐рдирд┐рдзрд┐рддреНрд╡ рдХрд░рддреА рд╣реИ:

| session_id | length_seconds |
| ------------ | ---------------- |
| 1 | 23 |
| 2 | 453 |
| 3 | 27 |
| .. | .. |

рдЯрд╛рд╕реНрдХ: рдкрд╛рдВрдЪ рд╕реЗрдХрдВрдб рдХреЗ рдЕрдВрддрд░рд╛рд▓ рдкрд░ рдЧрд┐рд░рдиреЗ рд╡рд╛рд▓реЗ рд╕рддреНрд░реЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреНрд╡реЗрд░реА рд▓рд┐рдЦреЗрдВ, рдЕрд░реНрдерд╛рдд рдЙрдкрд░реЛрдХреНрдд рдЦрдВрдб рдХреЗ рд▓рд┐рдП, рдкрд░рд┐рдгрд╛рдо рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╣реЛрдЧрд╛:

| рдмрд╛рд▓реНрдЯреА | рдЧрд┐рдирддреА |
| --------- | ------- |
| 20-25 | 2 |
| 450-455 | 1 |

рдЙрдЪрд┐рдд рд▓рд╛рдЗрди рд▓реЗрдмрд▓ рдХреЗ рд▓рд┐рдП рдЕрдзрд┐рдХрддрдо рдЕрдВрдХ рдорд╛рдпрдиреЗ рд░рдЦрддрд╛ рд╣реИ ("5-10", рдЖрджрд┐)

рд╕рдорд╛рдзрд╛рди:

WITH bin_label AS 
(SELECT 
    session_id, 
    FLOOR(length_seconds/5) as bin_label 
 FROM
    sessions 
 )
 SELECT 
    CONCATENTATE(STR(bin_label*5), '-', STR(bin_label*5+5)) bucket, 
    COUNT(DISTINCT session_id) count 
 GROUP BY 
    bin_label
 ORDER BY 
    bin_label ASC 

рдирдВрдмрд░ 2. рдХреНрд░реЙрд╕ рдХрдиреЗрдХреНрд╢рди (рдХрдИ рднрд╛рдЧреЛрдВ)


рднрд╛рдЧ 1


рд╕рдВрджрд░реНрдн: рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ state_streamsрдЬрд╣рд╛рдВ рд░рд╛рдЬреНрдп рдХрд╛ рдирд╛рдо рдФрд░ рд╡реАрдбрд┐рдпреЛ рд╣реЛрд╕реНрдЯрд┐рдВрдЧ рд╕реЗ рдХреБрд▓ рдШрдВрдЯреЗ рдХреА рд╕реНрдЯреНрд░реАрдорд┐рдВрдЧ рдХрд╛ рд╕рдВрдХреЗрдд рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ:

| рд░рд╛рдЬреНрдп | Total_streams |
| ------- | --------------- |
| рдПрдирд╕реА | 34569 |
| рдПрд╕рд╕реА | 33999 |
| рд╕реАрдП | 98324 |
| рдПрдордП | 19345 |
| .. | .. |

(рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ, рдЗрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдХреБрд▓ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдореЗрдВ рдЖрдорддреМрд░ рдкрд░ рдПрдХ рддрд┐рдерд┐ рд╕реНрддрдВрдн рднреА рд╣реЛрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рд╣рдо рдЗрд╕реЗ рдЗрд╕ рдХрд╛рд░реНрдп рдХреЗ рд▓рд┐рдП рдЫреЛрдбрд╝ рджреЗрдВрдЧреЗ)

рдХрд╛рд░реНрдп: рдПрдХ рджреВрд╕рд░реЗ рд╕реЗ рдПрдХ рд╣рдЬрд╝рд╛рд░ рдХреЗ рднреАрддрд░ рдХреБрд▓ рдзрд╛рдЧреЗ рдХреЗ рд╕рд╛рде рд░рд╛рдЬреНрдпреЛрдВ рдХреЗ рдЬреЛрдбрд╝реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреНрд░рд╢реНрди рд▓рд┐рдЦреЗрдВред рдЙрдкрд░реЛрдХреНрдд рд╕реНрдирд┐рдкреЗрдЯ рдХреЗ рд▓рд┐рдП, рд╣рдо рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рджреЗрдЦрдирд╛ рдЪрд╛рд╣реЗрдВрдЧреЗ:

| state_a | state_b |
| --------- | --------- |
| рдПрдирд╕реА | рдПрд╕рд╕реА |
| рдПрд╕рд╕реА | рдПрдирд╕реА |

рдлреЗрд╕рд▓рд╛:

SELECT
    a.state as state_a, 
    b.state as state_b 
 FROM   
    state_streams a
 CROSS JOIN 
    state_streams b 
 WHERE 
    ABS(a.total_streams - b.total_streams) < 1000
    AND 
    a.state <> b.state 

рдЬрд╛рдирдХрд╛рд░реА рдХреЗ рд▓рд┐рдП, рдХреНрд░реЙрд╕ рдЬреБрдбрд╝рдиреЗ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдП рдЧрдП рдЬрдВрдХреНрд╢рди рдХреЗ рдмрд┐рдирд╛ рднреА рд▓рд┐рдЦрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:

SELECT
    a.state as state_a, 
    b.state as state_b 
 FROM   
    state_streams a, state_streams b 
 WHERE 
    ABS(a.total_streams - b.total_streams) < 1000
    AND 
    a.state <> b.state 

рднрд╛рдЧ 2


рдиреЛрдЯ: рдпрд╣ рдПрдХ рдмрд╣реБрдд рд╣реА рдорд╣рддреНрд╡рдкреВрд░реНрдг SQL рдЯреЗрдореНрдкрд▓реЗрдЯ рдХреЗ рдмрдЬрд╛рдп рдПрдХ рдмреЛрдирд╕ рдкреНрд░рд╢реНрди рд╣реИред рдЖрдк рдЗрд╕реЗ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ!

рдХрд╛рд░реНрдп: рдореИрдВ рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЛ рдирд┐рдХрд╛рд▓рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд┐рдЫрд▓реЗ рд╕рдорд╛рдзрд╛рди рд╕реЗ SQL рдХреЛ рдХреИрд╕реЗ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реВрдВ? рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдПрдХ рд╣реА рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрджрд╛рд╣рд░рдг, рднрд╛рдк рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП NCрдФрд░ SCрдХреЗрд╡рд▓ рдПрдХ рд╣реА рд╕рдордп рдерд╛, рджреЛ рдирд╣реАрдВред

рдлреЗрд╕рд▓рд╛:

SELECT
    a.state as state_a, 
    b.state as state_b 
 FROM   
    state_streams a, state_streams b 
 WHERE 
    ABS(a.total_streams - b.total_streams) < 1000
    AND 
    a.state > b.state 

рдирдВрдмрд░ 3. рдЙрдиреНрдирдд рдЧрдгрдирд╛


рдЖрднрд╛рд░: рдпрд╣ рдХрд╛рд░реНрдп рдПрдХ рд╕рд╡рд╛рд▓ рдкрд░ рдЪрд░реНрдЪрд╛ рд╕реЗ рдЕрдиреБрдХреВрд▓рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рдерд╛ рдЬреЛ рдореИрдВрдиреЗ рд╕реНрдЯреИрдХрдСрд╡рд░рдлрд╝реНрд▓реЛ рдкрд░ рдкреВрдЫрд╛ рдерд╛ (рдореЗрд░рд╛ рдЙрдкрдирд╛рдо zthomas.nc рд╣реИ)ред

рдиреЛрдЯ: рдпрд╣ рд╕рдВрднрд╡рддрдГ рдПрдХ рдЕрдзрд┐рдХ рдХрдард┐рди рдХрд╛рд░реНрдп рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдПрдХ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рд╕рд╛рдХреНрд╖рд╛рддреНрдХрд╛рд░ рдореЗрдВ рдкреЗрд╢ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред рдЗрд╕реЗ рдПрдХ рдкрд╣реЗрд▓реА рдХреА рддрд░рд╣ рдЕрдзрд┐рдХ рд╕реЛрдЪреЗрдВ - рдпрд╛ рдЖрдк рдЗрд╕реЗ рдЫреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ!

рд╕рдВрджрд░реНрдн: рдорд╛рди рд▓реЗрдВ рдХрд┐ рд╣рдорд╛рд░реЗ рдкрд╛рд╕ tableрдЗрд╕ рддрд░рд╣ рдХреА рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рд╣реИ , рдЬрд╣рд╛рдВ userрдПрдХ рд╡рд░реНрдЧ рдХреЗ рд╡рд┐рднрд┐рдиреНрди рдореВрд▓реНрдп рдПрдХ рд╣реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЕрдиреБрд░реВрдк рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ class:

| рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ | рд╡рд░реНрдЧ |
| ------ | ------- |
| 1 | рдП |
| 1 | рдмреА |
| 1 | рдмреА |
| 2 | рдмреА |
| 3 | рдП |

рд╕рдорд╕реНрдпрд╛: рдорд╛рди рд▓реАрдЬрд┐рдП рдХрд┐ рдПрдХ рдХрдХреНрд╖рд╛ рдХреЗ рд▓рд┐рдП рдХреЗрд╡рд▓ рджреЛ рд╕рдВрднрд╛рд╡рд┐рдд рдорд╛рди рд╣реИрдВред рдкреНрд░рддреНрдпреЗрдХ рдХрдХреНрд╖рд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреА рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреНрд╡реЗрд░реА рд▓рд┐рдЦреЗрдВред рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рджреЛрдиреЛрдВ рд▓реЗрдмрд▓ рд╡рд╛рд▓реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ aрдФрд░ bрд╡рд░реНрдЧ рдХрд╛ рдЙрд▓реНрд▓реЗрдЦ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП bред

рд╣рдорд╛рд░реЗ рдирдореВрдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкрд░рд┐рдгрд╛рдо рдорд┐рд▓рддреЗ рд╣реИрдВ:

| рд╡рд░реНрдЧ | рдЧрд┐рдирддреА |
| ------- | ------- |
| рдП | 1 |
| рдмреА | 2 |

рдлреЗрд╕рд▓рд╛:

WITH usr_b_sum AS 
(
    SELECT 
        user, 
        SUM(CASE WHEN class = 'b' THEN 1 ELSE 0 END) num_b
    FROM 
        table
    GROUP BY 
        user
), 

usr_class_label AS 
(
    SELECT 
        user, 
        CASE WHEN num_b > 0 THEN 'b' ELSE 'a' END class 
    FROM 
        usr_b_sum
)

SELECT 
    class, 
    COUNT(DISTINCT user) count 
FROM
    usr_class_label
GROUP BY 
    class 
ORDER BY 
    class ASC

рдПрдХ рд╡реИрдХрд▓реНрдкрд┐рдХ рд╕рдорд╛рдзрд╛рди SELECTрдСрдкрд░реЗрдЯрд░реЛрдВ рдореЗрдВ рдирд┐рд░реНрджреЗрд╢реЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИ SELECTрдФрд░ UNION:

SELECT 
    "a" class,
    COUNT(DISTINCT user_id) - 
        (SELECT COUNT(DISTINCT user_id) FROM table WHERE class = 'b') count 
UNION
SELECT 
    "b" class,
    (SELECT COUNT(DISTINCT user_id) FROM table WHERE class = 'b') count 

All Articles