рдЧреНрд░рд╛рдлрд╛рдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рдореВрд╣реЛрдВ рдХреЛ рдЧреНрд░рд╛рдлрд╝ рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд╕реЗ рдПрдХрддреНрд░рд┐рдд рдХрд░реЗрдВ [+ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдбреЙрдХрд░ рдЫрд╡рд┐]

рдЧреНрд░рд╛рдлрд╛рдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рдореВрд╣реЛрдВ рдХреЛ рдЧреНрд░рд╛рдлрд╝ рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд╕реЗ рдПрдХрддреНрд░рд┐рдд рдХрд░реЗрдВ [+ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдбреЙрдХрд░ рдЫрд╡рд┐]

рд╣рдордиреЗ рдЧреНрд░рд╛рдлрд╛рдирд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдкреНрд░реЛрдореЛрдкрд▓реНрдЯ рд╕реЗрд╡рд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЗ рд╕рдореВрд╣реЛрдВ рдХреЛ рджреЗрдЦрдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рдХреИрд╕реЗ рд╣рд▓ рдХрд┐рдпрд╛ред

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

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

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

рд╕рд╛рд░рд╛рдВрд╢

  1. рд╕рдореВрд╣ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреНрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ?
  2. SQL рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрдВрдЬреАрдХрд░рдг рдХреЗ рдорд╣реАрдиреЗ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╕рдореВрд╣ рдХреИрд╕реЗ рдмрдирд╛рдПрдВред
  3. рд╕рдореВрд╣реЛрдВ рдХреЛ рдХреИрд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ рдЧреНрд░рд╛рдлрд╛рдирд╛.

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

1. рд╕рдореВрд╣ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреНрдпрд╛ рд╣реИ рдФрд░ рдЗрд╕рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ?

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

  • рдЕрдзрд┐рдЧреНрд░рд╣рдг рдЪреИрдирд▓ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЗ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЛ рдХреИрд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ;
  • рдХрд┐рд╕реА рд╕реБрд╡рд┐рдзрд╛ рдпрд╛ рд╕реЗрд╡рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЛ рдХреИрд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддрд╛ рд╣реИ;
  • рдкрд┐рдЫрд▓реЗ рд╡рд░реНрд╖ рдХреА рддреБрд▓рдирд╛ рдореЗрдВ рдлреАрдЪрд░ рдПрдХреНрд╕ рдХреЗ рд▓реЙрдиреНрдЪ рдиреЗ рдЬреАрд╡рдирдХрд╛рд▓ рдХреЛ рдХреИрд╕реЗ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд┐рдпрд╛ред

2. SQL рдореЗрдВ рдХреЛрд╣реЛрд░реНрдЯ рдХреИрд╕реЗ рдмрдирд╛рдПрдВ?

рд▓реЗрдЦ рдХрд╛ рдЖрдХрд╛рд░ рдФрд░ рд╕рд╛рдорд╛рдиреНрдп рдЬреНрдЮрд╛рди рд╣рдореЗрдВ рдЕрдкрдирд╛ рд╡рд╛рд╕реНрддрд╡рд┐рдХ рдбреЗрдЯрд╛ рдпрд╣рд╛рдВ рдкреНрд░рд╕реНрддреБрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрддрд╛ рд╣реИ - рдкрд░реАрдХреНрд╖рдг рдбрдВрдк рдореЗрдВ, рдбреЗрдврд╝ рд╕рд╛рд▓ рдХреЗ рдЖрдВрдХрдбрд╝реЗ: 1200 рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдФрд░ 53 рд▓реЗрдирджреЗрдиред рддрд╛рдХрд┐ рдЖрдк рдЗрд╕ рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рдЦреЗрд▓ рд╕рдХреЗрдВ, рд╣рдордиреЗ MySQL рдФрд░ Grafana рдХреЗ рд╕рд╛рде рдПрдХ рдбреЙрдХрд░ рдЫрд╡рд┐ рддреИрдпрд╛рд░ рдХреА рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдЖрдк рдпрд╣ рд╕рдм рд╕реНрд╡рдпрдВ рдЕрдиреБрднрд╡ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд▓реЗрдЦ рдХреЗ рдЕрдВрдд рдореЗрдВ GitHub рд╕реЗ рд▓рд┐рдВрдХ рдХрд░реЗрдВред

рдФрд░ рдпрд╣рд╛рдВ рд╣рдо рдПрдХ рд╕рд░рд▓ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдореВрд╣реЛрдВ рдХрд╛ рдирд┐рд░реНрдорд╛рдг рджрд┐рдЦрд╛рдПрдВрдЧреЗред

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

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

рдХрдЪреНрдЪрд╛ рдбреЗрдЯрд╛

рдЙрджрд╛рд╣рд░рдг MySQL рдореЗрдВ рдмрдирд╛рдП рдЧрдП рдереЗ, рд▓реЗрдХрд┐рди рдЕрдиреНрдп DBMS рдХреЗ рд▓рд┐рдП рдХреЛрдИ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдЕрдВрддрд░ рдирд╣реАрдВ рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рддрд╛рд▓рд┐рдХрд╛ - рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛:

рдпреВрдЬрд╝рд░ рдЖрдИрдбреА
рдкрдВрдЬреАрдХрд░рдг рдХреА рддрд╛рд░реАрдЦ

1
2019-01-01

2
2019-02-01

3
2019-02-10

4
2019-03-01

рд▓рд╛рдЧрдд рддрд╛рд▓рд┐рдХрд╛ - рдмрд┐рд▓рд┐рдВрдЧ:

рдпреВрдЬрд╝рд░ рдЖрдИрдбреА
рддрд╛рд░реАрдЦ
рд░рд╛рд╢рд┐

1
2019-01-02
11

1
2019-02-22
11

2
2019-02-12
12

3
2019-02-11
13

3
2019-03-11
13

4
2019-03-01
14

4
2019-03-02
14

рд╕рднреА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд░рд╛рдЗрдЯ-рдСрдлрд╝ рдФрд░ рдкрдВрдЬреАрдХрд░рдг рддрд┐рдерд┐ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ:

SELECT 
  b.userId, 
  b.Date,
  u.RegistrationDate
FROM billing AS b LEFT JOIN users AS u ON b.userId = u.userId

рд░рд┐рдЬрд▓реНрдЯ:

рдпреВрдЬрд╝рд░ рдЖрдИрдбреА
рддрд╛рд░реАрдЦ
рдкрдВрдЬреАрдХрд░рдг рдХреА рддрд╛рд░реАрдЦ

1
2019-01-02
2019-01-02

1
2019-02-22
2019-01-02

2
2019-02-12
2019-02-01

3
2019-02-11
2019-02-10

3
2019-03-11
2019-02-10

4
2019-03-01
2019-03-01

4
2019-03-02
2019-03-01

рд╣рдо рдорд╣реАрдиреЗ рдХреЗ рд╣рд┐рд╕рд╛рдм рд╕реЗ рд╕рдореВрд╣ рдмрдирд╛рддреЗ рд╣реИрдВ; рдРрд╕рд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо рд╕рднреА рддрд┐рдерд┐рдпреЛрдВ рдХреЛ рдорд╣реАрдиреЛрдВ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

DATE_FORMAT(Date, '%Y-%m')

рдЕрдм рд╣рдореЗрдВ рдпрд╣ рдЬрд╛рдирдиреЗ рдХреА рдЬрд░реВрд░рдд рд╣реИ рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд┐рддрдиреЗ рдорд╣реАрдиреЗ рд╕рдХреНрд░рд┐рдп рдерд╛ - рдпрд╣ рдбреЗрдмрд┐рдЯ рдХреЗ рдорд╣реАрдиреЗ рдФрд░ рдкрдВрдЬреАрдХрд░рдг рдХреЗ рдорд╣реАрдиреЗ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ рд╣реИред MySQL рдореЗрдВ рдПрдХ рдлрд╝рдВрдХреНрд╢рди PERIOD_DIFF() рд╣реИ - рджреЛ рдорд╣реАрдиреЛрдВ рдХреЗ рдмреАрдЪ рдХрд╛ рдЕрдВрддрд░ред рдЕрдиреБрд░реЛрдз рдореЗрдВ PERIOD_DIFF() рдЬреЛрдбрд╝реЗрдВ:

SELECT
    b.userId,
    DATE_FORMAT(b.Date, '%Y-%m') AS BillingMonth,
    DATE_FORMAT(u.RegistrationDate, '%Y-%m') AS RegistrationMonth,
    PERIOD_DIFF(DATE_FORMAT(b.Date, '%Y%m'), DATE_FORMAT(u.RegistrationDate, '%Y%m')) AS MonthsDiff
FROM billing AS b LEFT JOIN users AS u ON b.userId = u.userId

рдпреВрдЬрд╝рд░ рдЖрдИрдбреА
рдмрд┐рд▓рд┐рдВрдЧрдорд╣реАрдирд╛
рдкрдВрдЬреАрдХрд░рдг рдХреА рддрд╛рд░реАрдЦ
рдордВрдердбрд┐рдлрд╝

1
2019-01
2019-01
0

1
2019-02
2019-01
1

2
2019-02
2019-02
0

3
2019-02
2019-02
0

3
2019-03
2019-02
1

4
2019-03
2019-03
0

4
2019-03
2019-03
0

рд╣рдо рдкреНрд░рддреНрдпреЗрдХ рдорд╛рд╣ рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреА рдЧрдгрдирд╛ рдХрд░рддреЗ рд╣реИрдВ - рд╣рдо рдмрд┐рд▓рд┐рдВрдЧрдорд╛рдВрде, рд░рдЬрд┐рд╕реНрдЯреНрд░реЗрд╢рдирдорд╛рдВрде рдФрд░ рдордВрдердбрд┐рдл рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рд░рд┐рдХреЙрд░реНрдб рдХреЛ рд╕рдореВрд╣рд┐рдд рдХрд░рддреЗ рд╣реИрдВ:

SELECT
    COUNT(DISTINCT(b.userId)) AS UsersCount,
    DATE_FORMAT(b.Date, '%Y-%m') AS BillingMonth,
    DATE_FORMAT(u.RegistrationDate, '%Y-%m') AS RegistrationMonth,
    PERIOD_DIFF(DATE_FORMAT(b.Date, '%Y%m'), DATE_FORMAT(u.RegistrationDate, '%Y%m')) AS MonthsDiff
FROM billing AS b LEFT JOIN users AS u ON b.userId = u.userId
GROUP BY BillingMonth, RegistrationMonth, MonthsDiff

рд░рд┐рдЬрд▓реНрдЯ:

рдЙрдкрдпреЛрдХреНрддрд╛рдЧрдгрдирд╛
рдмрд┐рд▓рд┐рдВрдЧрдорд╣реАрдирд╛
рдкрдВрдЬреАрдХрд░рдгрдорд╛рд╣
рдордВрдердбрд┐рдлрд╝

1
2019-01
2019-01
0

1
2019-02
2019-01
1

2
2019-02
2019-02
0

1
2019-03
2019-02
1

1
2019-03
2019-03
0

рдЬрдирд╡рд░реА, рдлрд░рд╡рд░реА рдФрд░ рдорд╛рд░реНрдЪ рдореЗрдВ, рдкреНрд░рддреНрдпреЗрдХ рдореЗрдВ рдПрдХ рдирдпрд╛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджрд┐рдЦрд╛рдИ рджрд┐рдпрд╛ - рдордВрдереНрд╕рдбрд┐рдлрд╝ = 0. рдПрдХ рдЬрдирд╡рд░реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдлрд░рд╡рд░реА рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдерд╛ - рдкрдВрдЬреАрдХрд░рдг рдорд╛рд╣ = 2019-01, рдмрд┐рд▓рд┐рдВрдЧ рдорд╛рд╣ = 2019-02, рдФрд░ рдПрдХ рдлрд░рд╡рд░реА рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдорд╛рд░реНрдЪ рдореЗрдВ рд╕рдХреНрд░рд┐рдп рдерд╛ред

рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ, рдмрдбрд╝реЗ рдбреЗрдЯрд╛ рд╕реЗрдЯ рдореЗрдВ рдкреИрдЯрд░реНрди рдмреЗрд╣рддрд░ рджрд┐рдЦрд╛рдИ рджреЗрддреЗ рд╣реИрдВред

рдЧреНрд░реБрдкреЛрдВ рдХреЛ рдЧреНрд░рд╛рдлрд╛рдирд╛ рдореЗрдВ рдХреИрд╕реЗ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░реЗрдВ

рд╣рдордиреЗ рд╕рдореВрд╣ рдмрдирд╛рдирд╛ рд╕реАрдЦ рд▓рд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЬрдм рдмрд╣реБрдд рд╕рд╛рд░реЗ рд░рд┐рдХреЙрд░реНрдб рд╣реЛрдВ рддреЛ рдЙрдирдХрд╛ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░рдирд╛ рдЖрд╕рд╛рди рдирд╣реАрдВ рд░рд╣ рдЬрд╛рддрд╛ рд╣реИред рд░рд┐рдХреЙрд░реНрдбреНрд╕ рдХреЛ рдПрдХреНрд╕реЗрд▓ рдореЗрдВ рдирд┐рд░реНрдпрд╛рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдФрд░ рд╕реБрдВрджрд░ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдореЗрдВ рдмрдирд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдпрд╣ рд╣рдорд╛рд░реА рд╡рд┐рдзрд┐ рдирд╣реАрдВ рд╣реИ!

рд╕рдореВрд╣реЛрдВ рдХреЛ рдПрдХ рдЗрдВрдЯрд░реИрдХреНрдЯрд┐рд╡ рдЧреНрд░рд╛рдлрд╝ рдХреЗ рд░реВрдк рдореЗрдВ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдЧреНрд░рд╛рдлрд╛рдирд╛.

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

SELECT
  DATE_ADD(CONCAT(s.RegistrationMonth, '-01'), INTERVAL s.MonthsDiff MONTH) AS time_sec,
  SUM(s.Users) AS value,
  s.RegistrationMonth AS metric
FROM (
  ## ╤Б╤В╨░╤А╤Л╨╣ ╨╖╨░╨┐╤А╨╛╤Б, ╨▓╨╛╨╖╨▓╤А╨░╤Й╨░╤О╤Й╨╕╨╣ ╨║╨╛╨│╨╛╤А╤В╤Л
  SELECT 
    COUNT(DISTINCT(b.userId)) AS Users, 
    DATE_FORMAT(b.Date, '%Y-%m') AS BillingMonth,
    DATE_FORMAT(u.RegistrationDate, '%Y-%m') AS RegistrationMonth,
    PERIOD_DIFF(DATE_FORMAT(b.Date, '%Y%m'), DATE_FORMAT(u.RegistrationDate, '%Y%m')) AS MonthsDiff
  FROM billing AS b LEFT JOIN users AS u ON b.userId = u.userId
  WHERE
    u.RegistrationDate BETWEEN '2018-01-01' AND CURRENT_DATE
  GROUP BY 
    BillingMonth, RegistrationMonth, MonthsDiff 
) AS s
GROUP BY 
  time_sec, metric

рдФрд░ рдбреЗрдЯрд╛ рдХреЛ рдЧреНрд░рд╛рдлрд╛рдирд╛ рдкрд░ рдЕрдкрд▓реЛрдб рдХрд░реЗрдВред

рдЙрджрд╛рд╣рд░рдг рдЧреНрд░рд╛рдл рд╕реЗ рдбреЗрдореЛ:

рдЧреНрд░рд╛рдлрд╛рдирд╛ рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рд╕рдореВрд╣реЛрдВ рдХреЛ рдЧреНрд░рд╛рдлрд╝ рдХреЗ рд░реВрдк рдореЗрдВ рдХреИрд╕реЗ рдПрдХрддреНрд░рд┐рдд рдХрд░реЗрдВ [+ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рдбреЙрдХрд░ рдЫрд╡рд┐]

рдЕрдкрдиреЗ рд╣рд╛рдереЛрдВ рд╕реЗ рд╕реНрдкрд░реНрд╢ рдХрд░реЗрдВ:

рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде GitHub рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА MySQL рдФрд░ Grafana рдХреЗ рд╕рд╛рде рдПрдХ рдбреЙрдХрд░ рдЫрд╡рд┐ рд╣реИ рдЬрд┐рд╕реЗ рдЖрдк рдЕрдкрдиреЗ рдХрдВрдкреНрдпреВрдЯрд░ рдкрд░ рдЪрд▓рд╛ рд╕рдХрддреЗ рд╣реИрдВред рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдЬрдирд╡рд░реА 2018 рд╕реЗ рдЬреБрд▓рд╛рдИ 2019 рддрдХ, рдбреЗрдврд╝ рд╕рд╛рд▓ рдХрд╛ рдбреЗрдореЛ рдбреЗрдЯрд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред

рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ, рддреЛ рдЖрдк рдЕрдкрдирд╛ рдбреЗрдЯрд╛ рдЗрд╕ рдЫрд╡рд┐ рдореЗрдВ рд▓реЛрдб рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

SQL рдореЗрдВ рд╕рдореВрд╣ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ PS рд▓реЗрдЦ:

https://chartio.com/resources/tutorials/performing-cohort-analysis-using-mysql/

https://www.holistics.io/blog/calculate-cohort-retention-analysis-with-sql/

рд╕реНрд░реЛрдд: www.habr.com

рдПрдХ рдЯрд┐рдкреНрдкрдгреА рдЬреЛрдбрд╝реЗрдВ