YannickHelmut
YannickHelmut

Reputation: 555

Create temporary table to display missing months from query

I am trying to create a simple MySQL query to get the sales data for each month of the year, grouped by monthname and SalesName.

CREATE TEMPORARY TABLE Cal (monthid INT, monthname VARCHAR(50));
INSERT INTO Cal (monthid, monthname) VALUES
    (1, 'January'),
    (2, 'February'),
    (3, 'March'),
    (4, 'April'),
    (5, 'May'),
    (6, 'June'),
    (7, 'July'),
    (8, 'August'),
    (9, 'September'),
    (10, 'October'),
    (11, 'November'),
    (12, 'December');
CREATE TEMPORARY TABLE Sales AS SELECT SalesName FROM `Opportunity`;
SELECT concat(c.monthname, ' ', YEAR(CURDATE())) As `Period`,
s.SalesName,
IFNULL(CONVERT(AVG(o.GeneratedRevenue__c), SIGNED INTEGER), 0) As `AverageMonthlyRevenue`,
sum(CASE 
    WHEN c.monthid = Month(o.CloseDate)
    THEN o.Won
    ELSE 0
END) As `ClosedDeals`
FROM `Cal` c
join `Sales` s
left join `Opportunity` as o
on o.SalesName=s.SalesName and c.monthid=month(o.CloseDate)
GROUP By c.monthid, s.SalesName

The results are correct for the AverageMonthlyRevenue but return total nonsense for ClosedDeals.

Source database:

| Id | AccountName | SalesName | CloseDate | o.GeneratedRevenue__c | Won | Premium |
| -- | ------ | ------ | ------ | ------ | ------ | ------ |
|1|Mirazur|Grégoire|2020-05-19|1548|1|0
|2|Apicius|Edouard|2020-02-04|1344|1|1
|3|Arpège|Camille|2020-05-23|1456|1|1
|4|Les Apothicaires|Grégoire|2020-04-29|1635|1|0
|5|Le Bouillon|Camille|2020-12-10|1456|0|0
|6|Pink Mama|Edouard|2020-02-14|666|1|1

Result:

|Period | SalesName | AverageMonthlyRevenue| ClosedDeals |
| ------ | ------ | ------ |  ------ | 
|January 2020 | Camille     | 0     | 0 
|January 2020 | Edouard     | 0     | 0 
|January 2020 | Grégoire    | 0     | 0 
|February 2020 | Camille    | 0     | 0 
|February 2020 | Edouard    | 1005  | 4 
|February 2020 | Grégoire   | 0     | 0 
|March 2020 | Camille       | 0     | 0 
|March 2020 | Edouard       | 0     | 0 
|March 2020 | Grégoire      | 0     | 0 
|April 2020 | Camille       | 0     | 0 
|April 2020 | Edouard       | 0     | 0 
|April 2020 | Grégoire      | 1635  | 0 
|May 2020 | Camille         | 1456  | 2 
|May 2020 | Edouard         | 0     | 0 
|May 2020 | Grégoire        | 1548  | 0 
|June 2020 | Camille        | 0     | 0 
|June 2020 | Edouard        | 0     | 0 
|June 2020 | Grégoire       | 0     | 0 
|July 2020 | Camille        | 0     | 0 
|July 2020 | Edouard        | 0     | 0 
|July 2020 | Grégoire       | 0     | 0 
|August 2020 | Camille      | 0     | 0 
|August 2020 | Edouard      | 0     | 0 
|August 2020 | Grégoire     | 0     | 0 
|September 2020 | Camille   | 0     | 0 

Upvotes: 0

Views: 112

Answers (2)

Gordon Linoff
Gordon Linoff

Reputation: 1269703

You don't need temporary tables for this. Just use:

SELECT CONCAT(c.monthname, ' ', YEAR(CURDATE())) As Period,
s.SalesName,
       COALESCE(AVG(o.GeneratedRevenue__c), 0) As AverageMonthlyRevenue,
       COALESCE(SUM(o.won), 0) as ClosedDeals 
FROM Cal c CROSS JOIN
     (SELECT DISTINCT SalesName 
      FROM Opportunity s
     ) LEFT JOIN
     Opportunity o
     ON o.SalesName = s.SalesName AND
        c.monthid = MONTH(o.CloseDate)
GROUP BY c.monthid, s.SalesName;

Notes:

  • Your query doesn't take year into account. That seems quite dangerous.
  • You can use SELECT DISTINCT in the temporary table, although sales is unnecessary.
  • The ClosedDetails does not require a CASE expression.
  • JOIN should always have an ON clause -- even if MySQL allows such non-standard and confusing syntax. Use CROSS JOIN when that is what you intend.

Upvotes: 0

Marshall C
Marshall C

Reputation: 378

The error is in your Sales temporary table. Without adding DISTINCT you're just duplicating records. You need to do :

CREATE TEMPORARY TABLE Sales AS SELECT DISTINCT SalesName FROM `Opportunity`;

Upvotes: 1

Related Questions