0

我有一张这样的桌子:

VoerID   LogID  Status  Datum

1051        93  F   vr 08 okt 2004

1051    1037    A   di 19 okt 2004

1051    8955    A   di 18 jan 2005

1051    43972   A   wo 07 sep 2005

….  ….  ….. ……..

44444   10000000    V   someday 2013

所以每VoerID我有几个LogID。我想看到的是最新的logIDVoerID. 例如,我只看VoerID1051。

到目前为止已经做到了:

select Voer.ID, Datum, Status, maxLogID 
from  (SELECT VoerID, Datum, Status, MAX(LogID) as maxLogID 
FROM DB.Log group by VoerID order by Status)t1 where VoerID = '1051'

当我执行此操作时,答案是

VoerID  LogID   Status  Datum

1051    43972   F   vr 08 okt 2004

所以我得到了最新的 LogId,但没有得到相应的状态和日期。

如何解决这个问题?

4

3 回答 3

1

假设您定义了适当的索引,获取指定结果集(即一行)的最有效方法是:

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) 是唯一的。)

于 2013-07-08T14:56:39.000 回答
1

如果你真的想用双重选择来做到这一点,那么写这个的最糟糕的方法是......

    SELECT v.VoerID,v.LogID,v.Status,v.Datum From tableName v 
    INNER JOIN (Select MAX(LogID) as lastID, VoerID FROM tableName GROUP BY VoerID) r 
    ON v.LogID=r.lastID ORDER BY v.VoerID DESC

我并不是说这是最快或最好的方法,但您提供的数据和您提供的查询似乎是您想要完成的。如果您需要任何微调,请告诉我!

于 2013-07-08T15:06:40.060 回答
0

如果 LogID 总是在增加,你可以使用这个:

SELECT *
FROM yourtable
WHERE (VoerID, LogID) IN (SELECT VoerID, MAX(LogID)
                          FROM yourtable
                          GROUP BY VoerID)

子查询将返回每个 VoerID 的最大 LogID,外部查询将返回每个 voerid 具有最大 logid 的所有行。

于 2013-07-08T14:52:54.720 回答