Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server How To Return NULL Instead of 0 IF A GROUPED Value Doesn't Have Rows in Source

Here's a SQL Fiddle with the source data, what I've tried so far, and what I expect to get as output. http://sqlfiddle.com/#!18/daf90/2

I have a GameWinnings table, with rows containing Contestant name, the round he/she played, and the amount won in that round.

I need to produce a report that SUMs up all the winnings per round, by Contestant.

The condition I'm stuck in is that if a Contestant has not played in a particular round, the RoundWinningsAmount for that round should be NULL not 0. I think a CROSS APPLY or PIVOT / UNPIVOT might do it, haven't been able to nail it down yet.

Here's the table and initial data, followed by Problem statement and expected output vs what I've tried.

CREATE TABLE dbo.GameWinnings
(
    Contestant varchar(100) NOT NULL,
    GameRound int NOT NULL,
    RoundWinningsAmount numeric(38, 6) NULL
);

INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Ms Junaiqua',2,33333);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Mr Wang',1,NULL);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Mr Wang',1,NULL);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Mr Wang',1,100);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Mr Wang',2,NULL);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Thad Chad ',1,99);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Thad Chad ',1,1);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Thad Chad ',1,NULL);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Thad Chad ',2,50);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Thad Chad ',2,150);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Thad Chad ',2,NULL);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Thad Chad ',2,NULL);
INSERT INTO dbo.GameWinnings (Contestant,GameRound, RoundWinningsAmount) 
VALUES('Thad Chad ',3,300);

CREATE TABLE ExpectedOutput
(
Contestant varchar(100) NOT NULL,
Round_1_Winnings numeric(38, 6) NULL,
Round_2_Winnings numeric(38, 6) NULL,
Round_3_Winnings numeric(38, 6) NULL
); 

-- Expected output
INSERT INTO ExpectedOutput VALUES ('Mr Wang', 100 , 0 , NULL)
INSERT INTO ExpectedOutput VALUES ('Ms Junaiqua', NULL , 33333 , NULL)
INSERT INTO ExpectedOutput VALUES ('Thad Chad', 100 , 200 , 300)

IF you do a SELECT *, then this is the Data.

enter image description here

Problem Statement & Requirements

There are 3 Rounds in a Game. So GameRound column value will always be only 1 or 2 or 3.

  1. Create a resultset by Contestant, that SUMs up each contestants winning for each round
  2. If a contestant hasn't participated in a certain round, the SUM value for that round should be NULL, not 0

So in the sample data above

  1. Mr Wang has played in Round 1 and Round 2, but not in Round 3. So Round 3 SUM should be NULL not 0. Round 2 SUM should be 0 since he played in Round 2, but didn't win any money.
  2. Ms Junaiqua has played in Round 2 only, and not in Round 1 or Round 3, so Round 1 and Round 3 SUM should be NULL not 0.
  3. Thad Chad has played in all 3 Rounds, so all 3 Rounds should have the SUM value.

What I've tried

-- Current query I've tried to get desired output.
-- The query is returning 0, instead of NULL for Rounds where Contestant didn't participate.
-- I know that this is happening because I am returning 0 in the ELSE of the CASE.
-- Not sure how to fix it. 
SELECT
    Contestant,
    SUM ( CASE WHEN GameRound = 1 THEN RoundWinningsAmount ELSE 0 END) Round_1_Winnings,
    SUM ( CASE WHEN GameRound = 2 THEN RoundWinningsAmount ELSE 0 END) Round_2_Winnings,
    SUM ( CASE WHEN GameRound = 3 THEN RoundWinningsAmount ELSE 0 END) Round_3_Winnings
FROM dbo.GameWinnings
GROUP BY Contestant 

Expected Output vs Actual Output.

The values in Red need to be the values shown in green.

enter image description here

like image 890
Shiva Avatar asked Mar 07 '23 05:03

Shiva


1 Answers

you can use a PIVOT query like below:

see live demo

select * from 
(
    select 
        RoundWinnings=ISNULL(sum(RoundWinningsAmount),0),
        Contestant, 
        GameRound
    from GameWinnings
    group by Contestant, GameRound
)src
pivot
(
    max(RoundWinnings) 
    for GameRound in ([1],[2],[3])
 )p
like image 61
DhruvJoshi Avatar answered Mar 09 '23 00:03

DhruvJoshi