Как ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π² Π²ΠΈΠ΄Π΅ Π³Ρ€Π°Ρ„ΠΈΠΊΠΎΠ² Π² Grafana [+docker-ΠΎΠ±Ρ€Π°Π· с ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ]

Как ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π² Π²ΠΈΠ΄Π΅ Π³Ρ€Π°Ρ„ΠΈΠΊΠΎΠ² Π² Grafana [+docker-ΠΎΠ±Ρ€Π°Π· с ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ]

Как ΠΌΡ‹ Ρ€Π΅ΡˆΠΈΠ»ΠΈ Π·Π°Π΄Π°Ρ‡Ρƒ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΊΠΎΠ³ΠΎΡ€Ρ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π² сСрвисС Promopult c ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Grafana.

Promopult β€” ΠΌΠΎΡ‰Π½Ρ‹ΠΉ сСрвис с большим числом ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ. Π—Π° 10 Π»Π΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Ρ‹ число рСгистраций Π² систСмС ΠΏΠ΅Ρ€Π΅Π²Π°Π»ΠΈΠ»ΠΎ Π·Π° ΠΌΠΈΠ»Π»ΠΈΠΎΠ½. Π’Π΅, ΠΊΡ‚ΠΎ сталкивался с ΠΏΠΎΠ΄ΠΎΠ±Π½Ρ‹ΠΌΠΈ сСрвисами, Π·Π½Π°ΡŽΡ‚, Ρ‡Ρ‚ΠΎ этот массив ΡŽΠ·Π΅Ρ€ΠΎΠ² Π΄Π°Π»Π΅ΠΊΠΎ Π½Π΅ ΠΎΠ΄Π½ΠΎΡ€ΠΎΠ΄Π΅Π½.

ΠšΡ‚ΠΎ-Ρ‚ΠΎ зарСгался ΠΈ «уснул» Π½Π°Π²Π΅ΠΊΠΈ. ΠšΡ‚ΠΎ-Ρ‚ΠΎ Π·Π°Π±Ρ‹Π» ΠΏΠ°Ρ€ΠΎΠ»ΡŒ ΠΈ зарСгался Π΅Ρ‰Π΅ ΠΏΠ°Ρ€Ρƒ Ρ€Π°Π· Π·Π° ΠΏΠΎΠ»Π³ΠΎΠ΄Π°. ΠšΡ‚ΠΎ-Ρ‚ΠΎ нСсСт дСньги Π² кассу, Π° ΠΊΡ‚ΠΎ-Ρ‚ΠΎ ΠΏΡ€ΠΈΡˆΠ΅Π» Π·Π° халявными инструмСнтами. И Ρ…ΠΎΡ€ΠΎΡˆΠΎ Π±Ρ‹ с ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ Π½Π΅ΠΊΠΈΠΉ ΠΏΡ€ΠΎΡ„ΠΈΡ‚.

На Ρ‚Π°ΠΊΠΈΡ… Π±ΠΎΠ»ΡŒΡˆΠΈΡ… массивах Π΄Π°Π½Π½Ρ‹Ρ…, ΠΊΠ°ΠΊ Ρƒ нас, Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ ΡŽΠ·Π΅Ρ€Π° ΠΈ ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Ρ‚ΡŒ ΠΌΠΈΠΊΡ€ΠΎ-Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ бСссмыслСнно. А Π²ΠΎΡ‚ ΠΎΡ‚Π»Π°Π²Π»ΠΈΠ²Π°Ρ‚ΡŒ Ρ‚Ρ€Π΅Π½Π΄Ρ‹ ΠΈ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ с большими Π³Ρ€ΡƒΠΏΠΏΠ°ΠΌΠΈ β€” ΠΌΠΎΠΆΠ½ΠΎ ΠΈ Π½ΡƒΠΆΠ½ΠΎ. Π§Ρ‚ΠΎ ΠΌΡ‹, собствСнно, ΠΈ Π΄Π΅Π»Π°Π΅ΠΌ.

ΠšΡ€Π°Ρ‚ΠΊΠΎΠ΅ содСрТаниС

  1. Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Π½Ρ‹ΠΉ Π°Π½Π°Π»ΠΈΠ· ΠΈ Π·Π°Ρ‡Π΅ΠΌ ΠΎΠ½ Π½ΡƒΠΆΠ΅Π½.
  2. Как ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ ΠΏΠΎ мСсяцу рСгистрации ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π½Π° SQL.
  3. Как пСрСнСсти ΠΊΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ Π² Grafana.

Если Π²Ρ‹ ΡƒΠΆΠ΅ Π·Π½Π°Π΅Ρ‚Π΅, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Π½Ρ‹ΠΉ Π°Π½Π°Π»ΠΈΠ·, ΠΈ ΠΊΠ°ΠΊ Π΅Π³ΠΎ ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ Π½Π° SQL, сразу ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΈΡ‚Π΅ ΠΊ послСднСму Ρ€Π°Π·Π΄Π΅Π»Ρƒ.

1. Π§Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Π½Ρ‹ΠΉ Π°Π½Π°Π»ΠΈΠ· ΠΈ Π·Π°Ρ‡Π΅ΠΌ ΠΎΠ½ Π½ΡƒΠΆΠ΅Π½

ΠšΠΎΠ³ΠΎΡ€Ρ‚Π½Ρ‹ΠΉ Π°Π½Π°Π»ΠΈΠ· β€” это ΠΌΠ΅Ρ‚ΠΎΠ΄, основанный Π½Π° сравнСнии Ρ€Π°Π·Π½Ρ‹Ρ… Π³Ρ€ΡƒΠΏΠΏ (ΠΊΠΎΠ³ΠΎΡ€Ρ‚) ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ. Π§Π°Ρ‰Π΅ всСго Ρƒ нас Π³Ρ€ΡƒΠΏΠΏΡ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΠΎ Π½Π΅Π΄Π΅Π»Π΅ ΠΈΠ»ΠΈ мСсяцу, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π°Ρ‡Π°Π» ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ сСрвис. ΠžΡ‚ΡΡŽΠ΄Π° вычисляСтся врСмя ΠΆΠΈΠ·Π½ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ, Π° это ΡƒΠΆΠ΅ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚Π΅Π»ΡŒ, Π½Π° основС ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ³ΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡ€ΠΎΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ довольно слоТный Π°Π½Π°Π»ΠΈΠ·. НапримСр, ΠΏΠΎΠ½ΡΡ‚ΡŒ:

  • ΠΊΠ°ΠΊ влияСт ΠΊΠ°Π½Π°Π» привлСчСния Π½Π° врСмя ΠΆΠΈΠ·Π½ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Ρ;
  • ΠΊΠ°ΠΊ использованиС ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ ΠΈΠ»ΠΈ услуги влияСт Π½Π° врСмя ΠΆΠΈΠ·Π½ΠΈ;
  • ΠΊΠ°ΠΊ запуск Ρ„ΠΈΡ‡ΠΈ X повлиял Π½Π° врСмя ΠΆΠΈΠ·Π½ΠΈ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΏΡ€ΠΎΡˆΠ»Ρ‹ΠΌ Π³ΠΎΠ΄ΠΎΠΌ.

2. Как ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ Π½Π° SQL?

Π Π°Π·ΠΌΠ΅Ρ€ ΡΡ‚Π°Ρ‚ΡŒΠΈ ΠΈ Π·Π΄Ρ€Π°Π²Ρ‹ΠΉ смысл Π½Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡŽΡ‚ ΠΏΡ€ΠΈΠ²ΠΎΠ΄ΠΈΡ‚ΡŒ здСсь наши Ρ€Π΅Π°Π»ΡŒΠ½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ β€” Π² тСстовом Π΄Π°ΠΌΠΏΠ΅ статистика Π·Π° ΠΏΠΎΠ»Ρ‚ΠΎΡ€Π° Π³ΠΎΠ΄Π°: 1200 ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ ΠΈ 53 000 Ρ‚Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΉ. Π§Ρ‚ΠΎΠ±Ρ‹ Π²Ρ‹ ΠΌΠΎΠ³Π»ΠΈ ΠΏΠΎΠΈΠ³Ρ€Π°Ρ‚ΡŒ с этими Π΄Π°Π½Π½Ρ‹ΠΌΠΈ, ΠΌΡ‹ ΠΏΠΎΠ΄Π³ΠΎΡ‚ΠΎΠ²ΠΈΠ»ΠΈ docker-ΠΎΠ±Ρ€Π°Π· с MySQL ΠΈ Grafana, Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΌ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΡ‰ΡƒΠΏΠ°Ρ‚ΡŒ всС это самому. Бсылка Π½Π° GitHub Π² ΠΊΠΎΠ½Ρ†Π΅ ΡΡ‚Π°Ρ‚ΡŒΠΈ.

А здСсь ΠΌΡ‹ ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ созданиС ΠΊΠΎΠ³ΠΎΡ€Ρ‚ Π½Π° ΡƒΠΏΡ€ΠΎΡ‰Π΅Π½Π½ΠΎΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅.

ΠŸΡ€Π΅Π΄ΠΏΠΎΠ»ΠΎΠΆΠΈΠΌ, Ρ‡Ρ‚ΠΎ Ρƒ нас Π΅ΡΡ‚ΡŒ сСрвис. Π’ Π½Π΅ΠΌ Ρ€Π΅Π³ΠΈΡΡ‚Ρ€ΠΈΡ€ΡƒΡŽΡ‚ΡΡ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ ΠΈ тратят дСньги Π½Π° услуги. Π‘ΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ ΠΎΡ‚Π²Π°Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ. ΠœΡ‹ Ρ…ΠΎΡ‚ΠΈΠΌ ΡƒΠ·Π½Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ Π΄ΠΎΠ»Π³ΠΎ ΠΆΠΈΠ²ΡƒΡ‚ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΠΈ, ΠΈ сколько ΠΈΠ· Π½ΠΈΡ… отваливаСтся послС 1-Π³ΠΎ ΠΈ 2-Π³ΠΎ мСсяца использования сСрвиса.

Для ΠΎΡ‚Π²Π΅Ρ‚Π° Π½Π° эти вопросы Π½Π°ΠΌ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΡΡ‚Ρ€ΠΎΠΈΡ‚ΡŒ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ ΠΏΠΎ мСсяцу рСгистрации. ΠΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ Π±ΡƒΠ΄Π΅ΠΌ ΠΌΠ΅Ρ€ΡΡ‚ΡŒ ΠΏΠΎ расходам Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ мСсяцС. ВмСсто расходов ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Π·Π°ΠΊΠ°Π·Ρ‹, абонСнтская ΠΏΠ»Π°Ρ‚Π° ΠΈΠ»ΠΈ любая другая Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ, привязанная ΠΊΠΎ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ.

Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹ сдСланы Π² MySQL, Π½ΠΎ для ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Ρ… Π‘Π£Π‘Π” сущСствСнных ΠΎΡ‚Π»ΠΈΡ‡ΠΈΠΉ Π±Ρ‹Ρ‚ΡŒ Π½Π΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ.

Π’Π°Π±Π»ΠΈΡ†Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ β€” users:

userId
RegistrationDate

1
2019-01-01

2
2019-02-01

3
2019-02-10

4
2019-03-01

Π’Π°Π±Π»ΠΈΡ†Π° расходов β€” billing:

userId
Date
Sum

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

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

userId
Date
RegistrationDate

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

userId
BillingMonth
RegistrationDate
MonthsDiff

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

CΡ‡ΠΈΡ‚Π°Π΅ΠΌ Π°ΠΊΡ‚ΠΈΠ²ΠΈΡ€ΠΎΠ²Π°Π½Π½Ρ‹Ρ… Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ мСсяцС ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ β€” Π³Ρ€ΡƒΠΏΠΏΠΈΡ€ΡƒΠ΅ΠΌ записи ΠΏΠΎ BillingMonth, RegistrationMonth ΠΈ MonthsDiff:

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

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

UsersCount
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

Π’ январС, Ρ„Π΅Π²Ρ€Π°Π»Π΅ ΠΈ ΠΌΠ°Ρ€Ρ‚Π΅ появилось ΠΏΠΎ ΠΎΠ΄Π½ΠΎΠΌΡƒ Π½ΠΎΠ²ΠΎΠΌΡƒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŽ β€” MonthsDiff = 0. Один ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ января Π±Ρ‹Π» Π°ΠΊΡ‚ΠΈΠ²Π΅Π½ ΠΈ Π² Ρ„Π΅Π²Ρ€Π°Π»Π΅ β€” RegistrationMonth = 2019-01, BillingMonth = 2019-02, Ρ‚Π°ΠΊ ΠΆΠ΅ ΠΈ ΠΎΠ΄ΠΈΠ½ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ фСвраля Π±Ρ‹Π» Π°ΠΊΡ‚ΠΈΠ²Π΅Π½ Π² ΠΌΠ°Ρ€Ρ‚Π΅.

На большом массивС Π΄Π°Π½Π½Ρ‹Ρ… закономСрности, СстСствСнно, Π²ΠΈΠ΄Π½Ρ‹ Π»ΡƒΡ‡ΡˆΠ΅.

Как пСрСнСсти ΠΊΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ Π² Grafana

ΠšΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ Ρ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΌΡ‹ Π½Π°ΡƒΡ‡ΠΈΠ»ΠΈΡΡŒ, Π½ΠΎ ΠΊΠΎΠ³Π΄Π° записСй становится ΠΌΠ½ΠΎΠ³ΠΎ, Π°Π½Π°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ… ΡƒΠΆΠ΅ Π½Π΅Π»Π΅Π³ΠΊΠΎ. Записи ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΡΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² Excel ΠΈ ΡΡ„ΠΎΡ€ΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ красивыС Ρ‚Π°Π±Π»ΠΈΡ†Ρ‹, Π½ΠΎ это Π½Π΅ наш ΠΌΠ΅Ρ‚ΠΎΠ΄!

ΠšΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ Π² Π²ΠΈΠ΄Π΅ ΠΈΠ½Ρ‚Π΅Ρ€Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΠ³ΠΎ Π³Ρ€Π°Ρ„ΠΈΠΊΠ° Π² Grafana.

Для этого добавляСм Π΅Ρ‰Π΅ ΠΎΠ΄ΠΈΠ½ запрос, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΡ€Π΅ΠΎΠ±Ρ€Π°Π·ΠΎΠ²Π°Ρ‚ΡŒ Π΄Π°Π½Π½Ρ‹Π΅ Π² подходящий для Grafana Ρ„ΠΎΡ€ΠΌΠ°Ρ‚:

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

И Π²Ρ‹Π³Ρ€ΡƒΠΆΠ°Π΅ΠΌ Π΄Π°Π½Π½Ρ‹Π΅ Π² Grafana.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π³Ρ€Π°Ρ„ΠΈΠΊΠ° ΠΈΠ· Π΄Π΅ΠΌΠΎ:

Как ΡΠΎΠ±Ρ€Π°Ρ‚ΡŒ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Ρ‹ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»Π΅ΠΉ Π² Π²ΠΈΠ΄Π΅ Π³Ρ€Π°Ρ„ΠΈΠΊΠΎΠ² Π² Grafana [+docker-ΠΎΠ±Ρ€Π°Π· с ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ]

ΠŸΠΎΡ‚Ρ€ΠΎΠ³Π°Ρ‚ΡŒ Ρ€ΡƒΠΊΠ°ΠΌΠΈ:

GitHub-Ρ€Π΅ΠΏΠΎΠ·ΠΈΡ‚Π°Ρ€ΠΈΠΉ с ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ β€” это docker-ΠΎΠ±Ρ€Π°Π· с MySQL ΠΈ Grafana, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°ΠΏΡƒΡΡ‚ΠΈΡ‚ΡŒ Π½Π° своСм ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€Π΅. Π’ Π±Π°Π·Π΅ ΡƒΠΆΠ΅ Π΅ΡΡ‚ΡŒ Π΄Π΅ΠΌΠΎ-Π΄Π°Π½Π½Ρ‹Π΅ Π·Π° ΠΏΠΎΠ»Ρ‚ΠΎΡ€Π° Π³ΠΎΠ΄Π°, с января 2018 ΠΏΠΎ июль 2019 Π³ΠΎΠ΄Π°.

ΠŸΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ΠΌΠΎΠΆΠ½ΠΎ Π·Π°Π³Ρ€ΡƒΠ·ΠΈΡ‚ΡŒ свои Π΄Π°Π½Π½Ρ‹Π΅ Π² этот ΠΎΠ±Ρ€Π°Π·.

P.S. Π‘Ρ‚Π°Ρ‚ΡŒΠΈ ΠΏΡ€ΠΎ ΠΊΠΎΠ³ΠΎΡ€Ρ‚Π½Ρ‹ΠΉ Π°Π½Π°Π»ΠΈΠ· Π½Π° SQL:

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

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

Π˜ΡΡ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com