TL;DR - 使用子句分组后过滤日期HAVING,您可能还需要过滤 24 小时范围而不是单个日期(如果您的日期具有用户未显示的非午夜时间部分 -您正在使用的界面)。
让我们假设您有如下示例数据:
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;
并且您的NLS_DATE_FORMAT会话参数设置为 America/China/UK的默认值DD-MON-RR。
然后,如果您使用查询:
SELECT g.item_no,
MAX(g.exp_date)
FROM grn_drug_item g
GROUP BY g.item_no
你会得到输出:
项目_NO | MAX(G.EXP_DATE)
:--------- | :--------------
另一个001 | 20 年 8 月 5 日
其他00002 | 20 年 8 月 4 日
IT00002530 | 20 年 8 月 1 日
这符合您的以下陈述:
第一次查询仅显示 01-AUG-20 的以下结果
IT00002530 01-AUG-20
如果我们运行查询:
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
然后我们在分组前过滤行,并从过滤后的行中获得最大值;输出:
项目_NO | MAX(G.EXP_DATE)
:--------- | :-----------------
另一个001 | 2020-08-01T00:00:00
(NLS_DATE_FORMAT现在设置为 ISO8601 格式YYYY-MM-DD"T"HH24:MI:SS以显示时间分量)
这仅显示具有恰好ITEM_NO所在行的行。由于样本数据具有时间分量,因此未显示在结果中。EXP_DATE2020-08-01T00:00:00IT0000253012:00:00
要复制您的结果,我需要在 24 小时内过滤,而不是在午夜过滤一个实例:
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
这将输出:
项目_NO | MAX(G.EXP_DATE)
:--------- | :-----------------
另一个001 | 2020-08-01T00:00:00
IT00002530 | 2020-08-01T12:00:00
但是您似乎想要当天最大值所在的行,01-AUG-20因此您需要计算最大值然后对其进行过滤;您可以使用HAVING子句而不是WHERE子句来做到这一点:
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;
(同样,如果您的日期的时间部分并不总是设置为午夜,那么您希望过滤 24 小时范围而不是单个瞬间。)
哪个输出:
项目_NO | MAX(G.EXP_DATE)
:--------- | :-----------------
IT00002530 | 2020-08-01T12:00:00
db<>在这里摆弄