简体   繁体   中英

Getting data for a user in a month

(The database is Postgres )

Let's say I have a table races with columns (user_name , race_time , race_speed , race_no).

Each users can have multiple races . I want to get data for each month and show for each month how many races are played in that month. But I also want to show which user played the most and which played has the maximum speed.

select 
    extract ( month from race_time) as month,
    extract ( year from race_time) as year, 
    count(race_no) as total_races 
from races r
group by year,month
order by year desc,month desc

The above query gives me each month and the total races but how can I find for each month which user played the most (that'd be one user)?

I hope someone could help me with this.

SQL Fiddle

with r as (
    select
        to_char(race_time, 'YYYY-MM') as month,
        user_name,
        count(*) as n_races,
        max(race_speed) as max_speed
    from races
    group by 1, 2
), total_races as (
    select sum(n_races) as total_races, month
    from r
    group by month
)
select *
from (
        select distinct on (month)
            month, user_name as user_most_races, n_races as most_races
        from r
        order by 1, 3 desc
    ) s
    inner join (
        select distinct on (month)
            month, user_name as user_max_speed, max_speed
        from r
        order by 1, 3 desc
    ) q using (month)
    inner join
    total_races using(month)
order by month
SELECT COUNT(DISTINCT user_name), user_name, EXTRACT(month FROM race_time) AS month, EXTRACT(year FROM race_time) AS year
FROM races r
GROUP BY user_name, year, month
ORDER BY year desc, month desc

Try it!

USE [DATABASE_NAME]
GO

--this is calculating the which user played the most
CREATE FUNCTION [dbo].[GetHighestPlayedRaceUserByYearMonth] 
(
    -- Add the parameters for the function here
    @Year INT, @Month INT
)
RETURNS NVARCHAR(50)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @UserName NVARCHAR(50)

    -- Add the T-SQL statements to compute the return value here
    DECLARE @TempTbl TABLE(Played INT,UserName NVARCHAR(50))

    INSERT INTO @TempTbl(Played,UserName)
    SELECT 
        COUNT(race_no) AS Played,
        [user_name] AS UserName 

    FROM Table_1
    WHERE 
        YEAR(race_time)=@Year and
        MONTH(race_time)=@Month

    GROUP BY 
        MONTH(race_time),
        YEAR(race_time), 
        [user_name]
    ORDER BY 
        YEAR(race_time) DESC,
        MONTH(race_time) DESC, 
        COUNT(race_no) DESC

    DECLARE @MaxPlayed INT
    SET @MaxPlayed=(SELECT TOP 1 Played FROM @TempTbl ORDER BY Played DESC)

    DECLARE @TempTbl2 TABLE(ID INT IDENTITY(1,1) NOT NULL,UserName NVARCHAR(50))
    INSERT INTO @TempTbl2
    SELECT UserName FROM @TempTbl WHERE Played=@MaxPlayed

    DECLARE @ROWCOUNT INT
    SET @ROWCOUNT=1
    SET @UserName=''
    WHILE (SELECT COUNT(*) FROM @TempTbl2)>=@ROWCOUNT
    BEGIN
        IF (SELECT COUNT(*) FROM @TempTbl2)=@ROWCOUNT
        BEGIN
            SET @UserName= @UserName+(SELECT UserName FROM @TempTbl2 WHERE ID=@ROWCOUNT)
        END
        ELSE
        BEGIN
            SET @UserName= @UserName+(SELECT UserName FROM @TempTbl2 WHERE ID=@ROWCOUNT)+','
        END
        SET @ROWCOUNT=@ROWCOUNT+1
    END

    -- Return the result of the function
    RETURN @UserName

END

GO

--this is calculating which user played with the maximum speed
CREATE FUNCTION [dbo].[GetMaxRaceSpeedUserByYearMonth] 
(
    -- Add the parameters for the function here
    @Year INT, @Month INT
)
RETURNS NVARCHAR(50)
AS
BEGIN
    -- Declare the return variable here
    DECLARE @UserName NVARCHAR(50)

    -- Add the T-SQL statements to compute the return value here
    DECLARE @TempTbl TABLE(MaxRaceSpeed INT,UserName NVARCHAR(50))

    INSERT INTO @TempTbl(MaxRaceSpeed,UserName)
    SELECT 
        MAX(race_speed) AS MaxRaceSpeed,
        [user_name] AS UserName 

    FROM Table_1
    WHERE 
        YEAR(race_time)=@Year and
        MONTH(race_time)=@Month

    GROUP BY 
        MONTH(race_time),
        YEAR(race_time), 
        [user_name]
    ORDER BY 
        YEAR(race_time) DESC,
        MONTH(race_time) DESC, 
        COUNT(race_no) DESC

    DECLARE @MaxRaceSpeed INT
    SET @MaxRaceSpeed=(SELECT TOP 1 MaxRaceSpeed FROM @TempTbl ORDER BY MaxRaceSpeed DESC)

    DECLARE @TempTbl2 TABLE(ID INT IDENTITY(1,1) NOT NULL,UserName NVARCHAR(50))
    INSERT INTO @TempTbl2
    SELECT UserName FROM @TempTbl WHERE MaxRaceSpeed=@MaxRaceSpeed

    DECLARE @ROWCOUNT INT
    SET @ROWCOUNT=1
    SET @UserName=''
    WHILE (SELECT COUNT(*) FROM @TempTbl2)>=@ROWCOUNT
    BEGIN
        IF (SELECT COUNT(*) FROM @TempTbl2)=@ROWCOUNT
        BEGIN
            SET @UserName= @UserName+(SELECT UserName FROM @TempTbl2 WHERE ID=@ROWCOUNT)
        END
        ELSE
        BEGIN
            SET @UserName= @UserName+(SELECT UserName FROM @TempTbl2 WHERE ID=@ROWCOUNT)+','
        END
        SET @ROWCOUNT=@ROWCOUNT+1
    END

    -- Return the result of the function
    RETURN @UserName

END

GO

--Select Query
SELECT 
    MONTH(race_time) AS [Month],
    YEAR(race_time) AS [Year],
    COUNT(race_no) AS RacePlayed,
    dbo.GetHighestPlayedRaceUserByYearMonth(YEAR(race_time),MONTH(race_time)) AS MaximunPlayedUser,
    dbo.GetMaxRaceSpeedUserByYearMonth(YEAR(race_time),MONTH(race_time)) AS MaximunSpeedUser
FROM TABLE_NAME
GROUP BY MONTH(race_time),YEAR(race_time)
ORDER BY YEAR(race_time) DESC,MONTH(race_time) DESC

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM