sqlsql-server

Add a given value from a column based on the value from another column


I'm trying to generate a cars sales report using T-SQL.

The report must be grouped and ordered by Customer and Period (format M/yyyy)

The report result table must have the following columns:

You can find the SQL scripts I used to create and seed the database as well as the query I'm using here: https://dbfiddle.uk/wxFrkPuK

Here's the query I'm using in attempt to generate the report:

SELECT 
    c.Name_Customer AS 'Customer', 
    FORMAT(v.Sell_Date, 'M/yyyy') AS 'Period',
    CASE 
        WHEN t.Name_Vehicle_Type = 'Car' 
            THEN (COUNT(v.ID_Vehicle)) 
            ELSE NULL 
    END AS 'Cars quantity',
    CASE
        WHEN t.Name_Vehicle_Type = 'Car' 
            THEN SUM(v.Sell_Price) 
            ELSE NULL 
    END AS 'Cars total price',
    CASE 
        WHEN t.Name_Vehicle_Type = 'Truck' 
            THEN (COUNT(v.ID_Vehicle)) 
            ELSE NULL 
    END AS 'Trucks quantity',
    CASE
        WHEN t.Name_Vehicle_Type = 'Truck' 
            THEN SUM(v.Sell_Price) 
            ELSE NULL 
    END AS 'Trucks total price'
FROM
    Customer AS c, Vehicle AS v, Vehicle_Type AS t
WHERE 
    c.ID_Customer = v.ID_Customer 
    AND v.ID_Vehicle_Type = t.ID_Vehicle_Type
GROUP BY 
    v.ID_Customer, FORMAT(v.Sell_Date, 'M/yyyy'), 
    c.Name_Customer, v.ID_Customer, t.Name_Vehicle_Type
HAVING 
    (t.Name_Vehicle_Type = 'Car' OR t.Name_Vehicle_Type = 'Truck')
ORDER BY  
    c.Name_Customer, 'Period'

Here's what I get when running the query:

Customer Period Cars qnt Cars total price Trucks qnt Trucks total price
Jane Doe 2/2023 2 53000.00 NULL NULL
Jane Doe 2/2023 NULL NULL 2 380000.00
Jane Doe 4/2023 2 27000.00 NULL NULL
Jane Doe 4/2023 NULL NULL 2 137990.00
Jason St 5/2023 2 72500.00 NULL NULL
Jason St 5/2023 NULL NULL 2 330000.00
Jason St 8/2023 1 25000.00 NULL NULL
Jason St 8/2023 NULL NULL 1 57990.00
Mike Fen 6/2023 3 93500.00 NULL NULL
Mike Fen 6/2023 NULL NULL 2 330000.00

But I was expecting to receive:

Customer Period Cars qnt Cars total price Trucks qnt Trucks total price
Jane Doe 2/2023 2 53000.00 2 380000.00
Jane Doe 4/2023 2 27000.00 2 137990.00
Jason St 5/2023 2 72500.00 2 330000.00
Jason St 8/2023 1 25000.00 1 57990.00
Mike Fen 6/2023 3 93500.00 2 330000.00

Can you see the problem? It's generating an extra line with NULL values in certain cells. I wish to mix the two lines grouping by the customer and period as shown above.


Solution

  • You need to remove Name_Vehicle_Type from the grouping, and instead use conditional aggregation.

    Also:

    SELECT
      c.Name_Customer AS Customer,
      EOMONTH(v.Sell_Date AS Period,
      COUNT(CASE WHEN t.Name_Vehicle_Type = 'Car'   THEN 1 END) AS [Cars quantity],
      SUM  (CASE WHEN t.Name_Vehicle_Type = 'Car'   THEN v.Sell_Price END) AS [Cars total price],
      COUNT(CASE WHEN t.Name_Vehicle_Type = 'Truck' THEN 1 END) AS [Trucks quantity],
      SUM  (CASE WHEN t.Name_Vehicle_Type = 'Truck' THEN v.Sell_Price END) AS [Trucks total price]
    FROM Customer AS c
    JOIN Vehicle AS v ON c.ID_Customer = v.ID_Customer
    JOIN Vehicle_Type AS t ON v.ID_Vehicle_Type = t.ID_Vehicle_Type
    WHERE t.Name_Vehicle_Type IN ('Car', 'Truck')
    GROUP BY
      c.ID_Customer,
      c.Name_Customer,
      EOMONTH(v.Sell_Date)
    ORDER BY
      c.Name_Customer,
      EOMONTH(v.Sell_Date);