当状态 = N 时需要选择最大日期,否则 MYSQL 中没有

Need to Pick Max Date when status = N otherwise No in MYSQL

我有一个 table 有这样的记录

   ID           DATEADD        STATUS
'A0011'  '04/01/2018 11:58:31'  'C'
'A0011'  '31/05/2019 10:02:36'  'N'
'B0022'  '04/01/2018 11:58:31'  'N'
'B0022'  '31/05/2019 10:02:36'  'N'
'B0022'  '30/04/2020 19:44:36'  'C'
'C0033'  '04/01/2018 11:58:31'  'N'
'C0033'  '30/05/2019 06:02:36'  'C'
'C0033'  '29/04/2020 05:44:36'  'C'

我正在尝试获取状态 = 'N' 的每个 ID 的最大日期。如果我得到 MAX DATE 和 STATUS = 'C' 那么我不想要那个记录。

输出:

   ID           DATEADD        STATUS
'A0011'  '31/05/2019 10:02:36'  'N'

脚本:

SELECT I.* FROM INVOICE I
INNER JOIN (
Select ID,MAX(DATEADD)DATEADD,STATUS FROM INVOICE WHERE STATUS = 'N'
GROUP BY ID,STATUS) O
ON I.ID = O.ID AND O.DATEADD = I.DATEADD 

但我无法获得所需的输出。

如果你的mysql版本支持window函数,我们可以尝试使用ROW_NUMBERwindow函数获取每个ID最新的[=14] =] 然后比较 STATUS

SELECT *
FROM (
 SELECT *,ROW_NUMBER() OVER(PARTITION BY ID ORDER BY DATEADD DESC) rn
 FROM INVOICE
) t1
WHERE rn = 1 AND STATUS = 'N'

sqlfiddle

如果你的MySQL版本不支持window函数我们可以尝试使用关联子查询

SELECT *
FROM (
 SELECT *, (SELECT COUNT(*) 
            FROM INVOICE tt 
            WHERE tt.ID = t1.ID AND tt.DATEADD > t1.DATEADD) rn
 FROM INVOICE t1
) t1
WHERE rn = 1 AND STATUS = 'N'

sqlfiddle

我们可以使用 ORDER BYLIMIT 1 来获取我们想要的行,而无需使用任何函数、sub-queries、CTE 等
感谢 D-Shih 提供测试架构。 如果我们想要每个 ID 的状态为 'N' 的最大日期,我们可以使用第二个查询。

SELECT
  ID,
  DATEADD,
  STATUS
FROM INVOICE
ORDER BY 
  STATUS DESC,
  DATEADD DESC
LIMIT 1;
ID    | DATEADD    | STATUS
:---- | :--------- | :-----
A0011 | 2019-05-31 | N     
SELECT
  ID,
  MAX(DATEADD) AS DATEADD,
  STATUS
FROM INVOICE
WHERE STATUS = 'N'
GROUP BY ID
ORDER BY ID;
ID    | DATEADD    | STATUS
:---- | :--------- | :-----
A0011 | 2019-05-31 | N     
B0022 | 2019-05-31 | N     
C0033 | 2018-01-04 | N     

db<>fiddle here

您可以使用 NOT EXISTS:

SELECT i1.* 
FROM INVOICE i1
WHERE i1.STATUS = 'N'
  AND NOT EXISTS (
    SELECT 1
    FROM INVOICE i2
    WHERE i2.ID = i1.ID 
      AND STR_TO_DATE(i2.DATEADD, '%d/%m/%Y %H:%i:%s') > STR_TO_DATE(i1.DATEADD, '%d/%m/%Y %H:%i:%s')
  );

如果列的 DATEADD 数据类型是 DATETIMETIMESTAMP 最后一个条件会更简单:

...AND i2.DATEADD > i1.DATEADD

参见demo