简体   繁体   中英

Combining like rows in SQL and aggregating some values

I have some sample table of meaningless data, displayed below:

+--------+---------+---------+--------+---------+
| Vendor |   Day   |  Item   | Amount | Revenue |
+--------+---------+---------+--------+---------+
| Bob    | Monday  | Apple   |      1 |    1.00 |
| Bob    | Monday  | Orange  |      1 |    1.00 |
| Bob    | Monday  | Peach   |      2 |    2.00 |
| Bob    | Monday  | Lettuce |      3 |    3.00 |
| Bob    | Monday  | Spinach |      5 |    5.00 |
| Bob    | Monday  | Cabbage |      3 |    3.00 |
| Bob    | Tuesday | Apple   |      2 |    2.00 |
| Bob    | Tuesday | Orange  |      2 |    2.00 |
| Bob    | Tuesday | Peach   |      0 |    0.00 |
| Bob    | Tuesday | Lettuce |      3 |    3.00 |
| Bob    | Tuesday | Spinach |      5 |    5.00 |
| Bob    | Tuesday | Cabbage |      5 |    5.00 |
| Cindy  | Monday  | Apple   |      1 |    1.00 |
| Cindy  | Monday  | Orange  |      3 |    3.00 |
| Cindy  | Monday  | Peach   |      3 |    3.00 |
| Cindy  | Monday  | Lettuce |      6 |    6.00 |
| Cindy  | Monday  | Spinach |      8 |    8.00 |
| Cindy  | Monday  | Cabbage |      2 |    2.00 |
| Cindy  | Tuesday | Apple   |      1 |    1.00 |
| Cindy  | Tuesday | Orange  |      3 |    3.00 |
| Cindy  | Tuesday | Peach   |      0 |    0.00 |
| Cindy  | Tuesday | Lettuce |      2 |    2.00 |
| Cindy  | Tuesday | Spinach |      3 |    3.00 |
| Cindy  | Tuesday | Cabbage |      4 |    4.00 |
+--------+---------+---------+--------+---------+

I would like to combine values in Item into like categories, and condense the information down into fewer rows as this much detail is not necessary. For example, I'd like to take Apple, Orange, and Peach and turn those into "Fruit", and take Lettuce, Spinach, and Cabbage, and turn those into "Vegetable", all without losing the values stored in Amount and Revenue .

The table I am trying to achieve should look like this:

+--------+---------+-----------+--------+---------+
| Vendor |   Day   |   Item    | Amount | Revenue |
+--------+---------+-----------+--------+---------+
| Bob    | Monday  | Fruit     |      4 |    4.00 |
| Bob    | Monday  | Vegetable |     11 |   11.00 |
| Bob    | Tuesday | Fruit     |      4 |    4.00 |
| Bob    | Tuesday | Vegetable |     13 |   13.00 |
| Cindy  | Monday  | Fruit     |      7 |    7.00 |
| Cindy  | Monday  | Vegetable |     16 |   16.00 |
| Cindy  | Tuesday | Fruit     |      4 |    4.00 |
| Cindy  | Tuesday | Vegetable |      9 |    9.00 |
+--------+---------+-----------+--------+---------+

This is the current SQL query I have:

SELECT vendor, 
       day, 
       item_category, 
       Sum(amount), 
       Sum(revenue) 
FROM   (SELECT mytable.*, 
               CASE item 
                 WHEN 'Apple' THEN 'Fruit' 
                 WHEN 'Orange' THEN 'Fruit' 
                 WHEN 'Peach' THEN 'Fruit' 
                 WHEN 'Lettuce' THEN 'Vegetable' 
                 WHEN 'Spinach' THEN 'Vegetable' 
                 WHEN 'Cabbage' THEN 'Vegetable' 
               END AS item_category 
        FROM   mytable) AS x 
GROUP  BY vendor, 
          day, 
          item, 
          item_category;

This query is still returning a full list of rows instead of aggregating like rows. How would I modify it to achieve what I want to do?

You need to remove item from your group by statement. Below is more detail.

Since you are grabbing the item (apple, orange, etc) still it won't show them group solely by item_category until you remove the item from the top select and the group by.

Group by works by grouping by each unique combination of the statement, hence why item has to be removed.

see below. Note: I am renaming item_category as item so it looks as you has said you wanted the output as

SELECT vendor, 
   day, 
   item_category as item, 
   Sum(amount), 
   Sum(revenue) 
FROM   (SELECT mytable.*, 
           CASE item 
             WHEN 'Apple' THEN 'Fruit' 
             WHEN 'Orange' THEN 'Fruit' 
             WHEN 'Peach' THEN 'Fruit' 
             WHEN 'Lettuce' THEN 'Vegetable' 
             WHEN 'Spinach' THEN 'Vegetable' 
             WHEN 'Cabbage' THEN 'Vegetable' 
           END AS item_category 
    FROM   mytable) AS x 
GROUP  BY vendor, 
      day, 
      item_category;

You have to remove item from nested query and group by aggregation:

SELECT vendor, 
   day, 
   item_category, 
   Sum(amount), 
   Sum(revenue) 
FROM   (SELECT vendor, day, amount, revenue,
           CASE item 
             WHEN 'Apple' THEN 'Fruit' 
             WHEN 'Orange' THEN 'Fruit' 
             WHEN 'Peach' THEN 'Fruit' 
             WHEN 'Lettuce' THEN 'Vegetable' 
             WHEN 'Spinach' THEN 'Vegetable' 
             WHEN 'Cabbage' THEN 'Vegetable' 
           END AS item_category 
    FROM   mytable) AS x 
GROUP  BY vendor, 
      day, 
      item_category;

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