英文:
How to compare and filter rows in SQL by various columns
问题
正如您所见,FQDN和NAME可以相同,但TIMESTAMP始终不同。我一直在尝试删除旧记录,以仅保留最新的记录:
您能否请教是否有办法实现我的目标?
这是我迄今为止获得的SQL查询:
SELECT devices.fqdn, ports.pid, ports.name, ports.`status`, `subStatus`.`substatus`, updateLog.previousValue, updateLog.newValue, `updateLog`.`user`, `updateLog`.`timestamp`, `user`.`email`
FROM `updateLog`
LEFT JOIN `user` ON user.id = updateLog.user
LEFT JOIN ports ON updateLog.rowId=ports.pid
LEFT JOIN subStatus ON ports.subStatus=subStatus.id
LEFT JOIN slots ON ports.slot=slots.sid
LEFT JOIN devices ON slots.device=devices.did
WHERE (updateLog.rowId IN (select pid from ports where status=2))
AND (updateLog.columnName = 'status' AND updateLog.tableName = 'ports' and updateLog.newValue=2)
ORDER BY ports.pid asc LIMIT 1000;
英文:
I have a table with the following structure and content:
As you can see, there can be the same FQDN and NAME, however, TIMESTAMP is always different.
I have been trying to get rid of the old records in order to leave only the newest ones:
Could you please advise if there is a way for we to reach my goal?
Here is the SQL query I have got so far:
SELECT devices.fqdn, ports.pid, ports.name, ports.`status`, `subStatus`.`substatus`, updateLog.previousValue, updateLog.newValue, `updateLog`.`user`, `updateLog`.`timestamp`, `user`.`email`
FROM `updateLog`
LEFT JOIN `user` ON user.id = updateLog.user
LEFT JOIN ports ON updateLog.rowId=ports.pid
LEFT JOIN subStatus ON ports.subStatus=subStatus.id
LEFT JOIN slots ON ports.slot=slots.sid
LEFT JOIN devices ON slots.device=devices.did
WHERE (updateLog.rowId IN (select pid from ports where status=2))
AND (updateLog.columnName = 'status' AND updateLog.tableName = 'ports' and updateLog.newValue=2)
ORDER BY ports.pid asc LIMIT 1000;
答案1
得分: 1
要获取每个组的顶部行通常使用窗口函数来解决(这里可以使用MAX OVER
、ROW_NUMBER
、RANK
或DENSE_RANK
)。
以下是使用ROW_NUMBER
的查询:
SELECT *
FROM
(
SELECT
d.fqdn,
p.pid, p.name, p.status,
ss.substatus,
ul.previousvalue, ul.newvalue, ul.user, ul.timestamp,
user.email,
ROW_NUMBER() OVER (PARTITION BY d.fqdn, p.name ORDER BY ul.timestamp DESC) AS rn
FROM updatelog ul
LEFT JOIN ports p ON ul.rowId = p.pid
LEFT JOIN substatus ss ON p.ss = ss.id
LEFT JOIN slots s ON p.slot = s.sid
LEFT JOIN devices d ON s.device = d.did
WHERE ul.rowId IN (SELECT pid FROM ports WHERE status = 2)
AND ul.columnname = 'status'
AND ul.tablename = 'p'
AND ul.newvalue = 2
) ranked
WHERE rn = 1;
英文:
To get the top row(s) per group is usually solved with window functions (either MAX OVER
here, ROW_NUMBER
, RANK
or DENSE_RANK
).
Here is the query with ROW_NUMBER
:
SELECT *
FROM
(
SELECT
d.fqdn,
p.pid, p.name, p.status,
ss.substatus,
ul.previousvalue, ul.newvalue, ul.user, ul.timestamp,
user.email,
ROW_NUMBER() OVER (PARTITION BY d.fqdn, p.name ORDER BY ul.timestamp DESC) AS rn
FROM updatelog ul
LEFT JOIN ports p ON ul.rowId = p.pid
LEFT JOIN substatus ss ON p.ss = ss.id
LEFT JOIN slots s ON p.slot = s.sid
LEFT JOIN devices d ON s.device = d.did
WHERE ul.rowId IN (SELECT pid FROM ports WHERE status = 2)
AND ul.columnname = 'status'
AND ul.tablename = 'p'
AND ul.newvalue = 2
) ranked
WHERE rn = 1;
答案2
得分: 0
SELECT DISTINCT timestamp FROM table
LEFT JOIN SELECT other rows
英文:
SELECT DISTINCT timestamp FROM table
LEFT JOIN SELECT other rows
答案3
得分: 0
获取每个(fqdn和name)的最新时间戳:
SELECT fqdn, name, MAX(Timestamp)
FROM tableName
GROUP BY fqdn, name
如果您需要返回其他字段:
SELECT t1.fqdn, t1.name, t1.user, t1.Timestamp
FROM tableName t1
WHERE timestamp = (
SELECT MAX(timestamp)
FROM tableName t2 WHERE t1.fqdn = t2.fqdn AND t1.name = t2.name
)
英文:
To get the latest timestamp from each (fqdn and name):
SELECT fqdn, name, MAX(Timestamp)
FROM tableName
GROUP BY fqdn, name
If you need to return other fields:
SELECT t1.fqdn, t1.name, t1.user, t1.Timestamp
FROM tableName t1
WHERE timestamp = (
SELECT MAX(timestamp)
FROM tableName t2 WHERE t1.fqdn = s2.fqdn AND t1.name = t2.name
)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论