简体   繁体   中英

How to count occurrences between multiple dates and list only unique rows from MySQL?

i have searched an answer for this but haven't figured out a proper solution. I have a database with one table 'data', where i have all products listed with their expiry dates. Total number of different products is somewhere around 120, but 'data'-table has over 5000 rows. Every product has multiple individual, expiry-monitored units.

I would need to list all unique products with columns for occurrences of expiry dates in each year. Currently i run multiple another queries for each year inside iteration of main query to count occurrences of expiry dates between two dates.

CREATE TABLE IF NOT EXISTS `data` (
`EXPIRY` date DEFAULT NULL,
`RNO` int(6) DEFAULT NULL,
`PRODID` int(3) DEFAULT NULL,
`NAME` varchar(38) DEFAULT NULL,
`RND` varchar(2) DEFAULT NULL,
`RDY` varchar(3) DEFAULT NULL,
`ARTY` varchar(3) DEFAULT NULL,
`ARYK` varchar(4) DEFAULT NULL,
`BATCH` varchar(16) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

// list all unique product rows
$main_loop = $database->query('SELECT * FROM data GROUP BY rno HAVING COUNT(*) >=1');
$rows = $database->resultset($main_loop);
foreach($rows as $data) {
  echo "<tr>";
    echo "<td>".$data['RNO']."</td>";
    <td>
  // another query to count occurrences of expiry in each product between two dates
  $thisrno = $data['RNO'];
  $database->query("SELECT * FROM data WHERE EXP BETWEEN '2016-01-01' AND '2016-12-31' AND RNO = '$thisrno'");
  $database->execute();
  $rows = $database->rowCount();
  echo $rows;
  echo "</td><td>";
  ...i would need to do this for each column (2016-2025)
  ...
}

I'd believe that there is better solution for this. Problem is also, that this way i cannot sort the table by the number of expiring units each year and this is not very efficient.

The result should be like:

RNO    | NAME        | Expiring in 2016 | Expiring in 2017 | ...
336540 | Prod_name_1 | 34               | 62               |
391755 | Prod_name_2 | 2                | 116              |
653112 | Prod_name_3 | 46               | 7                |

Seems fairly straightforward:

select rno, name,
    sum(exp between '2016-01-01' and '2016-12-31') as exp2016,
    sum(exp between '2017-01-01' and '2017-12-31') as exp2017,
    sum(exp between '2018-01-01' and '2018-12-31') as exp2018,
    sum(exp between '2019-01-01' and '2019-12-31') as exp2019,
    sum(exp between '2020-01-01' and '2020-12-31') as exp2020,
    sum(exp between '2021-01-01' and '2021-12-31') as exp2021,
    sum(exp between '2022-01-01' and '2022-12-31') as exp2022,
    sum(exp between '2023-01-01' and '2023-12-31') as exp2023,
    sum(exp between '2024-01-01' and '2024-12-31') as exp2024,
    sum(exp between '2025-01-01' and '2025-12-31') as exp2025
from data
where exp between '2016-01-01' and '2025-12-31'
group by rno;

If you want to include even products that have no expirations in those years, omit the where clause.

I'm not sure what your question is about sorting; you could pick one year and sort the rows by that year's counts of expirations, but that seems a little strange.

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