假设您定义了适当的索引,获取指定结果集(即一行)的最有效方法是:
SELECT VoerID
, Datum
, Status
, LogID
FROM DB.Log
WHERE VoerID = '1051'
ORDER
BY VoerID DESC
, LogID DESC
LIMIT 1
要获取多个 VoerID 的最新行(即每个 VoerID 的 MAX(LogID)),您可以对内联视图使用 JOIN 操作:
SELECT l.VoerID
, l.Datum
, l.Status
, l.LogID
FROM (
SELECT k.VoerID
, MAX(k.LogID) AS LogID
FROM DB.Log k
GROUP BY k.VoerID
) m
JOIN DB.Log l
ON l.VoerID = m.VoerID AND l.LogID = m.LogID
ORDER BY l.VoerID ASC
为了两个查询的性能,您需要定义一个索引ON (VoerID, LogID)
跟进
问:我还想计算每个状态的 VoerID 数量。每个月底都可以这样做吗?然后可能还必须考虑列时间戳logID...
答: 我没有将 Datum 列识别为时间戳列。
要获取出现具有特定状态的行的 VoerID 的简单计数:
SELECT l.Status
, COUNT(DISTINCT l.VoerID)
FROM DB.Log l
GROUP BY l.Status
您对“月末”的提及可以用几种不同的方式来解释。您是否想要一个 VoerID 计数,其中一个月内的最新 LogID 是特定状态,或者您是否希望计数包括一个月内具有特定状态的任何 VoerID。
目前尚不清楚您正在寻找什么结果集,但这可能会给您一个想法。
可以在时间戳列上添加一个函数表达式,以从时间戳中获取年份和月份,例如
DATE_FORMAT(timestampcol,'%Y-%m') AS yyyymm
如果您想将其作为日期返回(如果这在您的代码中比处理字符串更方便),例如每月的第一天:
DATE_FORMAT(timestampcol,'%Y-%m-01') + INTERVAL 0 DAY AS yyyymm
(如果该列是字符串,而不是 DATE、DATETIME 或 TIMESTAMP 列,则可以使用函数在查询中对其进行转换。)
如果您只想查看每个 VoerID 的“最新”LogID,如上面查询返回的行,则可以使用以下方法:
SELECT l.status
, m.yyyymm
, COUNT(DISTINCT m.VoerID) AS count_distinct_voerid
FROM (
SELECT k.VoerID
, DATE_FORMAT(k.timestampcol,'%Y-%m-01') + INTERVAL 0 DAY AS yyyymm
, MAX(k.LogID) AS LogID
FROM DB.Log k
GROUP
BY k.VoerID
, DATE_FORMAT(k.timestampcol,'%Y-%m-01') + INTERVAL 0 DAY
) m
JOIN DB.Log l
ON l.VoerID = m.VoerID AND l.LogID = m.LogID
ORDER BY m.yyyymm DESC, l.status ASC
(实际上,关键字 DISTINCT 可以省略,在本例中它是多余的,假设 (LogID) 是唯一的,或者 (VoerID,LogID) 是唯一的。)