Nur Oktaviani
Nur Oktaviani

Reputation: 21

How to group rows in MySQL with condition

I have this table:

| id | part number | serial_number | qty |
==========================================
| 1  | A           | 12345         | 1   |
| 2  | A           | 54321         | 1   |
| 3  | A           | 67890         | 1   |
| 4  | B           |               | 10  |
| 5  | B           |               | 5   |
| 6  | C           |               | 6   |
| 7  | C           |               | 3   |

I want to group the rows like this:

| id | part number | serial_number | qty |
==========================================
| 1  | A           | 12345         | 1   |
| 2  | A           | 54321         | 1   |
| 3  | A           | 67890         | 1   |
| 4  | B           |               | 10  |
| 6  | C           |               | 6   |

How to do this? Is this possible or not?

I want group the row by part number that doesn't have serial number. So if I have 4 rows with same part number that doesn't have serial number, it's only display 1 row.

Upvotes: 0

Views: 70

Answers (2)

LukStorms
LukStorms

Reputation: 29677

This looks more like a job for NOT EXISTS.

For those that have a NULL serial_number you want only to keep those with the lowest id per part_number.

So you just need to filter those you don't need.

SELECT *
FROM YourTable t
WHERE NOT EXISTS
(
   SELECT 1 
   FROM YourTable d
   WHERE d.`part number` = t.`part number`
     AND d.serial_number IS NULL
     AND t.serial_number IS NULL
     AND d.id < t.id
)
ORDER BY id;

Result:

id | part number | serial_number | qty
-- | ----------- | ------------- | ---
 1 | A           |         12345 |   1
 2 | A           |         54321 |   1
 3 | A           |         67890 |   1
 4 | B           |         null  |  10
 6 | C           |         null  |   6

Test on db<>fiddle here

Btw, in MySql 5.x, when the ONLY_FULL_GROUP_BY setting isn't active.
Then this would give the same result.
But then it won't only be for those with NULL serial_number.

SELECT *
FROM YourTable 
GROUP BY `part number`, serial_number
ORDER BY id

Test here

Upvotes: 2

Tim Biegeleisen
Tim Biegeleisen

Reputation: 522762

This looks like you just want to aggregate by the combination of the part number and serial_number, taking the max quantity:

SELECT
    MIN(t1.id) AS id, t1.part_number, t1.serial_number, t1.qty
FROM yourTable t1
INNER JOIN
(
    SELECT part_number, serial_number, MAX(qty) AS qty
    FROM yourTable
    GROUP BY part_number, serial_number
) t2
    ON t1.part_number = t2.part_number AND
       (t1.serial_number = t2.serial_number OR
        t1.serial_number IS NULL AND t2.serial_number IS NULL) AND
       t1.qty = t2.qty
GROUP BY
    t1.part_number,
    t1.serial_number,
    t1.qty
ORDER BY
    MIN(t1.id);

Demo

Note that null is a legitimate value to form a member of a group in a GROUP BY operation.

Upvotes: 2

Related Questions