diff --git a/dal/db_query/queries.sql b/dal/db_query/queries.sql index 1859c04..3447961 100644 --- a/dal/db_query/queries.sql +++ b/dal/db_query/queries.sql @@ -520,19 +520,20 @@ WITH Funnel AS ( ), Questions AS ( SELECT + q.id, q.title AS question_title, a.content AS answer_content, COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage FROM answer a JOIN ( - SELECT q.id, COUNT(*) AS total_answers + SELECT q.id, q.title, COUNT(*) AS total_answers FROM question q JOIN answer a ON q.id = a.question_id WHERE a.quiz_id = $1 AND a.created_at >= TO_TIMESTAMP($2) AND a.created_at <= TO_TIMESTAMP($3) - GROUP BY q.id + GROUP BY q.id, q.title ) q ON a.question_id = q.id WHERE a.quiz_id = $1 diff --git a/dal/sqlcgen/queries.sql.go b/dal/sqlcgen/queries.sql.go index 8afc21d..79a8fc1 100644 --- a/dal/sqlcgen/queries.sql.go +++ b/dal/sqlcgen/queries.sql.go @@ -1573,6 +1573,144 @@ func (q *Queries) MoveToHistoryQuiz(ctx context.Context, arg MoveToHistoryQuizPa return i, err } +const questionsStatistics = `-- name: QuestionsStatistics :many +WITH Funnel AS ( + SELECT + COUNT(DISTINCT session) FILTER (WHERE a.start = FALSE) AS count_start_false, + COUNT(DISTINCT session) FILTER (WHERE a.start = TRUE) AS count_start_true, + COUNT(DISTINCT CASE WHEN a.result = FALSE AND qid_true_result IS NOT NULL THEN session END) AS count_f_result_with_t_question, + COUNT(DISTINCT CASE WHEN a.start = TRUE AND qid_true_result IS NULL THEN session END) AS count_t_start_with_t_question, + COUNT(DISTINCT session) FILTER (WHERE a.result = TRUE) AS count_t_result + FROM + answer a + LEFT JOIN ( + SELECT DISTINCT a.session, q.id AS qid_true_result + FROM answer a + JOIN question q ON a.question_id = q.id + WHERE a.result = TRUE + ) AS q ON a.session = q.session + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) +), + Results AS ( + SELECT + q.title AS question_title, + COUNT(*)::FLOAT / NULLIF(SUM(COUNT(*)) FILTER (WHERE a.result = TRUE), 0) AS percentage + FROM + answer a + JOIN + question q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + AND a.result = TRUE + GROUP BY + q.id, q.title + HAVING + COUNT(*) >= 1 + ), + Questions AS ( + SELECT + q.id, + q.title AS question_title, + a.content AS answer_content, + COUNT(*)::FLOAT / NULLIF(q.total_answers, 0) AS percentage + FROM + answer a + JOIN ( + SELECT q.id, q.title, COUNT(*) AS total_answers + FROM question q + JOIN answer a ON q.id = a.question_id + WHERE a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY q.id, q.title + ) q ON a.question_id = q.id + WHERE + a.quiz_id = $1 + AND a.created_at >= TO_TIMESTAMP($2) + AND a.created_at <= TO_TIMESTAMP($3) + GROUP BY + q.id, q.title, a.content + HAVING + COUNT(*) >= 1 + ) +SELECT + Funnel.count_start_false, + Funnel.count_start_true, + Funnel.count_f_result_with_t_question, + Funnel.count_t_start_with_t_question, + Funnel.count_t_result, + Funnel.count_start_true, + Results.question_title AS results_question_title, + Results.percentage AS results_percentage, + Questions.question_title AS questions_question_title, + Questions.answer_content AS questions_answer_content, + Questions.percentage AS questions_percentage +FROM + Funnel, + Results, + Questions +` + +type QuestionsStatisticsParams struct { + QuizID int64 `db:"quiz_id" json:"quiz_id"` + ToTimestamp float64 `db:"to_timestamp" json:"to_timestamp"` + ToTimestamp_2 float64 `db:"to_timestamp_2" json:"to_timestamp_2"` +} + +type QuestionsStatisticsRow struct { + CountStartFalse int64 `db:"count_start_false" json:"count_start_false"` + CountStartTrue int64 `db:"count_start_true" json:"count_start_true"` + CountFResultWithTQuestion int64 `db:"count_f_result_with_t_question" json:"count_f_result_with_t_question"` + CountTStartWithTQuestion int64 `db:"count_t_start_with_t_question" json:"count_t_start_with_t_question"` + CountTResult int64 `db:"count_t_result" json:"count_t_result"` + CountStartTrue_2 int64 `db:"count_start_true_2" json:"count_start_true_2"` + ResultsQuestionTitle string `db:"results_question_title" json:"results_question_title"` + ResultsPercentage int32 `db:"results_percentage" json:"results_percentage"` + QuestionsQuestionTitle string `db:"questions_question_title" json:"questions_question_title"` + QuestionsAnswerContent sql.NullString `db:"questions_answer_content" json:"questions_answer_content"` + QuestionsPercentage int32 `db:"questions_percentage" json:"questions_percentage"` +} + +func (q *Queries) QuestionsStatistics(ctx context.Context, arg QuestionsStatisticsParams) ([]QuestionsStatisticsRow, error) { + rows, err := q.db.QueryContext(ctx, questionsStatistics, arg.QuizID, arg.ToTimestamp, arg.ToTimestamp_2) + if err != nil { + return nil, err + } + defer rows.Close() + var items []QuestionsStatisticsRow + for rows.Next() { + var i QuestionsStatisticsRow + if err := rows.Scan( + &i.CountStartFalse, + &i.CountStartTrue, + &i.CountFResultWithTQuestion, + &i.CountTStartWithTQuestion, + &i.CountTResult, + &i.CountStartTrue_2, + &i.ResultsQuestionTitle, + &i.ResultsPercentage, + &i.QuestionsQuestionTitle, + &i.QuestionsAnswerContent, + &i.QuestionsPercentage, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Close(); err != nil { + return nil, err + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const softDeleteResultByID = `-- name: SoftDeleteResultByID :exec UPDATE answer SET deleted = TRUE WHERE id = $1 AND deleted = FALSE `