当状态 = 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_NUMBER
window函数获取每个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'
如果你的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'
我们可以使用 ORDER BY
和 LIMIT 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
数据类型是 DATETIME
或 TIMESTAMP
最后一个条件会更简单:
...AND i2.DATEADD > i1.DATEADD
参见demo。
我有一个 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_NUMBER
window函数获取每个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'
如果你的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'
我们可以使用 ORDER BY
和 LIMIT 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
数据类型是 DATETIME
或 TIMESTAMP
最后一个条件会更简单:
...AND i2.DATEADD > i1.DATEADD
参见demo。