行返回/最新记录中的Mysql错误值

时间:2013-07-08 14:50:00

标签: mysql group-by record

我有一张这样的表:

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。我希望看到的是logIDVoerIDVoerID。 举个例子,我只会看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' 1051。

到目前为止已经做到了这一点:

VoerID  LogID   Status  Datum

1051    43972   F   vr 08 okt 2004

执行此操作时答案是

{{1}}

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

如何解决这个问题?

3 个答案:

答案 0 :(得分: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

您对“月末”的提及可以通过几种不同的方式进行解释。您是否想要计算一个月内最新LogID为特定状态的VoerID,或者您是否希望计数包含一个月内具有特定状态的任何VoerID。

目前尚不清楚您正在寻找什么样的结果集,但这可能会给您一个想法。

可以添加一个表达式,该表达式是timestamp列的一个函数,用于从时间戳中获取年份和月份,例如

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

答案 1 :(得分: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

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

答案 2 :(得分:0)

如果LogID始终在增加,您可以使用:

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

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