diff --git a/db/db.go b/db/db.go index 9ff0cfb..12ca748 100644 --- a/db/db.go +++ b/db/db.go @@ -185,15 +185,17 @@ func (d *DB) AdjustKM(ctx context.Context, guildID, userID, username string, km // ── Stats Queries ───────────────────────────────────────────────────────────── func (d *DB) GetLeaderboard(ctx context.Context, guildID string, since time.Time, limit int) ([]*UserStats, error) { - q := `SELECT user_id, username, SUM(km), COUNT(*), MAX(logged_at) - FROM distance_logs WHERE guild_id = $1` + q := `SELECT user_id, + (SELECT username FROM distance_logs sub WHERE sub.user_id = dl.user_id AND sub.guild_id = dl.guild_id ORDER BY logged_at DESC LIMIT 1), + SUM(km), COUNT(*), MAX(logged_at) + FROM distance_logs dl WHERE guild_id = $1` args := []interface{}{guildID} if !since.IsZero() { args = append(args, since) q += fmt.Sprintf(` AND logged_at >= $%d`, len(args)) } args = append(args, limit) - q += fmt.Sprintf(` GROUP BY user_id, username ORDER BY SUM(km) DESC LIMIT $%d`, len(args)) + q += fmt.Sprintf(` GROUP BY user_id ORDER BY SUM(km) DESC LIMIT $%d`, len(args)) rows, err := d.conn.QueryContext(ctx, q, args...) if err != nil { @@ -227,14 +229,16 @@ func (d *DB) GetTotalKM(ctx context.Context, guildID string, since time.Time) (f } func (d *DB) GetUserStats(ctx context.Context, guildID, userID string, since time.Time) (*UserStats, error) { - q := `SELECT user_id, username, COALESCE(SUM(km), 0), COUNT(*), COALESCE(MAX(logged_at)::text, '') - FROM distance_logs WHERE guild_id = $1 AND user_id = $2` + q := `SELECT user_id, + COALESCE((SELECT username FROM distance_logs sub WHERE sub.user_id = dl.user_id AND sub.guild_id = dl.guild_id ORDER BY logged_at DESC LIMIT 1), ''), + COALESCE(SUM(km), 0), COUNT(*), COALESCE(MAX(logged_at)::text, '') + FROM distance_logs dl WHERE guild_id = $1 AND user_id = $2` args := []interface{}{guildID, userID} if !since.IsZero() { args = append(args, since) q += fmt.Sprintf(` AND logged_at >= $%d`, len(args)) } - q += ` GROUP BY user_id, username` + q += ` GROUP BY user_id` s := &UserStats{} err := d.conn.QueryRowContext(ctx, q, args...).Scan( @@ -247,10 +251,12 @@ func (d *DB) GetUserStats(ctx context.Context, guildID, userID string, since tim func (d *DB) GetStatsInRange(ctx context.Context, guildID string, from, to time.Time, limit int) ([]*UserStats, error) { rows, err := d.conn.QueryContext(ctx, ` - SELECT user_id, username, SUM(km), COUNT(*), MAX(logged_at) - FROM distance_logs + SELECT user_id, + (SELECT username FROM distance_logs sub WHERE sub.user_id = dl.user_id AND sub.guild_id = dl.guild_id ORDER BY logged_at DESC LIMIT 1), + SUM(km), COUNT(*), MAX(logged_at) + FROM distance_logs dl WHERE guild_id = $1 AND logged_at >= $2 AND logged_at <= $3 - GROUP BY user_id, username + GROUP BY user_id ORDER BY SUM(km) DESC LIMIT $4 `, guildID, from, to, limit) @@ -303,10 +309,12 @@ type YearTotal struct { func (d *DB) GetYearlyLeaderboard(ctx context.Context, guildID string, year, limit int) ([]*UserStats, error) { rows, err := d.conn.QueryContext(ctx, ` - SELECT user_id, username, SUM(km), COUNT(*), MAX(logged_at) - FROM distance_logs + SELECT user_id, + (SELECT username FROM distance_logs sub WHERE sub.user_id = dl.user_id AND sub.guild_id = dl.guild_id ORDER BY logged_at DESC LIMIT 1), + SUM(km), COUNT(*), MAX(logged_at) + FROM distance_logs dl WHERE guild_id = $1 AND EXTRACT(YEAR FROM logged_at) = $2 - GROUP BY user_id, username + GROUP BY user_id ORDER BY SUM(km) DESC LIMIT $3 `, guildID, year, limit) @@ -332,10 +340,12 @@ func (d *DB) GetUserYearlyStats(ctx context.Context, guildID, userID string, yea s := &UserStats{UserID: userID} var lastUpdated sql.NullTime err := d.conn.QueryRowContext(ctx, ` - SELECT user_id, username, COALESCE(SUM(km), 0), COUNT(*), MAX(logged_at) - FROM distance_logs + SELECT user_id, + (SELECT username FROM distance_logs sub WHERE sub.user_id = dl.user_id AND sub.guild_id = dl.guild_id ORDER BY logged_at DESC LIMIT 1), + COALESCE(SUM(km), 0), COUNT(*), MAX(logged_at) + FROM distance_logs dl WHERE guild_id = $1 AND user_id = $2 AND EXTRACT(YEAR FROM logged_at) = $3 - GROUP BY user_id, username + GROUP BY user_id `, guildID, userID, year).Scan(&s.UserID, &s.Username, &s.TotalKM, &s.LogCount, &lastUpdated) if err == sql.ErrNoRows { return s, nil