SQL - 使用Max创建的时间戳值返回数据的不同行

时间:2013-08-09 10:12:14

标签: sql database sybase

在我的程序中,我审核传入的数据,可以是4种类型。如果数据符合所有必需条件,则会成功存储在表列中,以及将行输入表中的消息类型和时间戳。

由于类似连接问题和审计等问题,数据也可能会被错误地写入表中。程序将重试审核此数据,如果成功将写入新行,则成功。因此,您看到我现在有2行用于该特定数据消息,一行成功,一行有错误,两者都有不同的时间戳。 (成功具有最新时间戳而不是错误记录。)

第三条消息被拒绝,如果传入的数据不符合要求的标准,则会写入记录,再次使用创建时间戳。

我想做的是编写一个Sybase SQL查询,以便仅撤回每个收到的消息的记录,并且时间戳最高。

因此,使用上面的错误示例,我不想返回错误记录,只返回重复进程并且成功的相应成功记录。

我曾想过类似以下内容......

SELECT distinct(*) 
    FROM auditingTable
        WHERE timestamp = (SELECT MAX(timestamp) from auditingTable)

虽然我知道这只会带回1条记录,整个表中的时间戳最高。

我怎样才能收到收到的每封邮件的最新记录,无论其状态如何?

欢迎任何想法!

3 个答案:

答案 0 :(得分:5)

您尚未提及Sybase版本。 您可以使用ROW_NUMBER() function

例如,您的表格包含MessageIdMessageTime个字段,您可以在查询后使用这些字段:

SELECT * FROM
 (
    SELECT auditingTable.*,
    ROW_NUMBER() OVER (PARTITION BY MessageID ORDER BY MessageTime DESC) as RN
    FROM auditingTable 
  ) as T
WHERE RN=1; 

答案 1 :(得分:4)

我想要注意的是,对查询的简单修改可以让你做你想做的事情(尽管我更喜欢Valex答案中的row_number()方法)。这是将where子句中的子查询转换为相关子查询:

SELECT *
FROM auditingTable at1
WHERE timestamp = (SELECT MAX(timestamp)
                   from auditingTable at2
                   where at1.MessageId = at2.MessageId
                  );

这是标准SQL,应该适用于任何版本的Sybase。

答案 2 :(得分:0)

我建议在auditingTable添加自动增量主键字段,以便更轻松地识别记录。对于以下查询,我假设您已添加此列并将其命名为auditRecordId

假设您正在通过messageType识别每条消息,那么以下内容应该有效:

SELECT      A1.messageType,
            A1.message
FROM        auditingTable A1
INNER JOIN  (
                SELECT      MAX(auditRecordId) auditRecordId,
                            messageType
                FROM        auditingTable
                GROUP BY    messageType
            ) A2 ON A1.auditRecordId = A2.auditRecordId