package statistics import ( "context" "database/sql" "fmt" ) type DepsClick struct { Conn *sql.DB } type StatisticClick struct { conn *sql.DB } func NewClickStatistic(ctx context.Context, deps DepsClick) (*StatisticClick, error) { s := &StatisticClick{ conn: deps.Conn, } err := s.checkMW(ctx) if err != nil { fmt.Println("error check material view existing", err) return nil, err } return s, nil } func (s *StatisticClick) checkMW(ctx context.Context) error { query := ` CREATE MATERIALIZED VIEW IF NOT EXISTS mv_last_answers_events ENGINE = MergeTree() ORDER BY (ctxsession, event_time) POPULATE AS SELECT event_time, ctxsession, ctxquizid, ctxquestionid, ctxidint, message,ctxquiz FROM statistics WHERE message IN ('InfoQuizOpen', 'InfoAnswer', 'InfoResult') AND event_level = 'info'; ` _, err := s.conn.ExecContext(ctx, query) if err != nil { return err } return nil } type Statistic struct { Count int64 QuestionID int64 } type PipeLineStatsResp map[int64][]Statistic func (s *StatisticClick) GetPipelinesStatistics(ctx context.Context, quizID int64, from uint64, to uint64) (PipeLineStatsResp, error) { pipelines := make(PipeLineStatsResp) query := ` select last_quesion, questions, count() from (select last_quesion, questions, target_quiz from (select last_quesion, questions, target_quiz from view_pipelines_signs join view_respondent_paths on long_sess = session array join questions) as pipelines join mv_answers on questions=questionid and quizid=target_quiz where target_quiz = ? AND event_time BETWEEN ? AND ? ) group by last_quesion, questions; ` rows, err := s.conn.QueryContext(ctx, query, quizID, from, to) if err != nil { return nil, err } defer rows.Close() for rows.Next() { var lastQuestionID int64 var questionID int64 var count int64 if err := rows.Scan(&lastQuestionID, &questionID, &count); err != nil { return nil, err } stat := Statistic{ Count: count, QuestionID: questionID, } pipelines[lastQuestionID] = append(pipelines[lastQuestionID], stat) } if err := rows.Err(); err != nil { return nil, err } return pipelines, nil }