TL;DR - Filter on date after grouping using the HAVING
clause and you may also need to filter on a 24-hour range rather than a single date (if your dates have a non-midnight time component that is not being displayed by the user-interface you are using).
Lets assume that you have sample data that is something like this:
CREATE TABLE grn_drug_item ( item_no, exp_date ) AS
SELECT 'IT00002530', DATE '2020-08-01' + INTERVAL '12:00:00' HOUR TO SECOND FROM DUAL UNION ALL
SELECT 'IT00002530', DATE '2020-07-01' FROM DUAL UNION ALL
SELECT 'ANOTHER001', DATE '2020-08-01' FROM DUAL UNION ALL
SELECT 'ANOTHER001', DATE '2020-08-05' FROM DUAL UNION ALL
SELECT 'OTHER00002', DATE '2020-07-01' FROM DUAL UNION ALL
SELECT 'OTHER00002', DATE '2020-08-04' FROM DUAL;
And your NLS_DATE_FORMAT
session parameter is set to the default for America/China/UK of DD-MON-RR
.
Then if you use your query:
SELECT g.item_no,
MAX(g.exp_date)
FROM grn_drug_item g
GROUP BY g.item_no
You will get the output:
ITEM_NO | MAX(G.EXP_DATE)
:--------- | :--------------
ANOTHER001 | 05-AUG-20
OTHER00002 | 04-AUG-20
IT00002530 | 01-AUG-20
Which matches your statement of:
1st query only displays following result for 01-AUG-20
IT00002530 01-AUG-20
If we run the query:
SELECT g.item_no,
MAX(g.exp_date)
FROM grn_drug_item g
WHERE g.exp_date = DATE '2020-08-01'
GROUP BY g.item_no
Then we are filtering the rows before grouping and will get the maximum from the filtered rows; which outputs:
ITEM_NO | MAX(G.EXP_DATE)
:--------- | :------------------
ANOTHER001 | 2020-08-01T00:00:00
(The NLS_DATE_FORMAT
is now set to the ISO8601 format YYYY-MM-DD"T"HH24:MI:SS
to display the time component as well)
This only shows the rows ITEM_NO
that have a row where the EXP_DATE
is exactly 2020-08-01T00:00:00
. Since the sample data for IT00002530
has a time component of 12:00:00
it is not showing in the results.
To replicate your results I would need to filter on a 24 hour period and not a single instance at midnight:
SELECT g.item_no,max(g.exp_date)
FROM grn_drug_item g
WHERE g.exp_date >= DATE '2020-08-01'
AND g.exp_date < DATE '2020-08-01' + INTERVAL '1' DAY
GROUP BY g.item_no
Which would output:
ITEM_NO | MAX(G.EXP_DATE)
:--------- | :------------------
ANOTHER001 | 2020-08-01T00:00:00
IT00002530 | 2020-08-01T12:00:00
But you appear to want the rows where the maximum is on the day 01-AUG-20
so you would need to calculate the maximum and then filter on that; which you can do using a HAVING
clause rather than a WHERE
clause:
SELECT g.item_no,
MAX(g.exp_date)
FROM grn_drug_item g
GROUP BY g.item_no
HAVING MAX(g.exp_date) >= DATE '2020-08-01'
AND MAX(g.exp_date) < DATE '2020-08-01' + INTERVAL '1' DAY;
(Again, if your dates have a time component that is not always set to midnight then you want to filter on a 24 hour range rather than on a single instant.)
Which outputs:
ITEM_NO | MAX(G.EXP_DATE)
:--------- | :------------------
IT00002530 | 2020-08-01T12:00:00
db<>fiddle here