I have the following table:
+-------------+--------------+
| product | purchased |
+-------------+--------------+
| Hammer | |
|
What you need to work with is whether the warranty is still valid or expired and the warranty date, so you first need to build a table that reflects that:
select product
, IF( warranty >= NOW(), 1, 0 ) as valid
, IF( warranty < NOW(), 1, 0 ) as expired
, warranty as last
from (
select product
, ADDDATE( purchased, INTERVAL 5 YEAR ) as warranty
from productWarranty
) w
group by product
;
That would get you something like that:
+---------+-------+---------+---------------------+
| product | valid | expired | warranty |
+---------+-------+---------+---------------------+
| Hammer | 1 | 0 | 2017-01-01 00:00:00 |
| Nipper | 1 | 0 | 2017-01-01 00:00:00 |
| Nipper | 1 | 0 | 2017-01-01 00:00:00 |
| Nipper | 1 | 0 | 2017-01-01 00:00:00 |
| Saw | 1 | 0 | 2017-01-01 00:00:00 |
| Saw | 0 | 1 | 2011-01-01 00:00:00 |
| Saw | 1 | 0 | 2017-01-01 00:00:00 |
| Saw | 1 | 0 | 2017-01-01 00:00:00 |
+---------+-------+---------+---------------------+
Then use aggregate functions to filter and sum up the information you're looking for:
select product
, SUM( IF( warranty >= NOW(), 1, 0 ) ) as valid
, SUM( IF( warranty < NOW(), 1, 0 ) ) as expired
, MAX( warranty ) as last
from (
select product
, affffdate( purchased, interval 5 year ) as warranty
from productWarranty
) w
group by product
;
+---------+-------+---------+---------------------+
| product | valid | expired | last |
+---------+-------+---------+---------------------+
| Hammer | 1 | 0 | 2017-01-01 00:00:00 |
| Nipper | 3 | 0 | 2017-01-01 00:00:00 |
| Saw | 3 | 1 | 2017-01-01 00:00:00 |
+---------+-------+---------+---------------------+
Here's the answer I posted in your other question
SELECT p2c.pid AS productNumber,
p.name AS productName,
COUNT(*) AS registered,
SUM(date_add(from_unixtime(purchased), INTERVAL 5 YEAR) >= CURDATE()) AS inWarranty,
SUM(date_add(from_unixtime(purchased), INTERVAL 5 YEAR) < CURDATE()) AS outOfWarranty,
DATE_FORMAT( MAX( from_unixtime(purchased) ), '%d.%m.%Y') AS lastPurchased,
DATE_FORMAT( date_add( MAX( from_unixtime(purchased) ), INTERVAL 5 YEAR), '%d.%m.%Y') AS warrantyUntil
FROM products2customers p2c
JOIN products p ON p.id = p2c.pid
GROUP BY p2c.pid
ORDER BY inWarranty DESC
Better normalization would speed up this query tremendously, but here's an example to work from:
First, you need to start with your base query, the one that will drive the results. In this case, it's a list of all the products in your table:
SELECT DISTINCT product
FROM productWarranty
The above query creates a sort of "temp" table that we can base our queries on. If you have a separate, normalized product table then that would be much better.
The rest of the columns can simply be subqueries driven by your base table:
Total count:
SELECT COUNT(*)
FROM productWarranty
WHERE product = 'Hammer'
Total valid warranties:
SELECT COUNT(*)
FROM productWarranty
WHERE product = 'Hammer'
AND purchased >= <warranty cut-off date>
Total expired warranties:
SELECT COUNT(*)
FROM productWarranty
WHERE product = 'Hammer'
AND purchased < <warranty cut-off date>
Last purchase date:
SELECT MAX( purchased )
FROM productWarranty
WHERE product = 'Hammer'
Now to combine all of these into a single query:
SELECT Base.product
, (
SELECT COUNT(*)
FROM productWarranty
WHERE product = Base.product
) AS TotalCount
, (
SELECT COUNT(*)
FROM productWarranty
WHERE product = Base.product
AND date_add(from_unixtime(purchased), INTERVAL 5 YEAR) >= CURDATE()
) AS ValidWarrantyCount
, (
SELECT COUNT(*)
FROM productWarranty
WHERE product = Base.product
AND date_add(from_unixtime(purchased), INTERVAL 5 YEAR) < CURDATE()
) AS ExpiredWarrantyCount
, (
SELECT MAX( purchased )
FROM productWarranty
WHERE product = Base.product
) AS LastPurchased
FROM (
SELECT DISTINCT product
FROM productWarranty
) AS Base