【问题标题】:Return detail data related to the corresponding MAX(datetime) value返回与对应的 MAX(datetime) 值相关的详细数据
【发布时间】:2013-03-16 16:32:52
【问题描述】:

我有以下使用 SQL Server 2005 的数据集:

TABLE NAME: LOG

TYPE       TIMESTAMP            USERID
Job        26/03/2013 00:24     DED
Job        21/03/2013 02:31     EGA
Sales      NULL                 NULL
Sales      NULL                 NULL

我想根据 MA​​X(timestamp) 检索列 TYPE、TIMESTAMP 和 USERID.. 即结果应该是

Job        26/03/2013 00:24     DED

我尝试了以下方法

SELECT max(timestamp), UserID
FROM log
GROUP BY UserID

但是返回所有行。

当我尝试时

SELECT max(timestamp), max(UserID)
FROM log
GROUP BY UserID

返回

Job        26/03/2013 00:24     EGA

我知道返回的 max(userID) 是按字母顺序排序的最大列值。

最后当我尝试

SELECT * 
FROM log 
WHERE timestamp = (SELECTmax(timestamp) FROM log)

我没有得到任何结果(空)..

如果有人能提供帮助,将不胜感激!


编辑更新:

如果有任何帮助-我应该提到我有多个表,并且需要 SELECT USERIDMAX(timestamp)WHERE TYPE` 可以等于(“工作”或“销售”)。

我发现这非常有效:

SELECT Type,
       MAX(CASE WHEN log.Type IN ('Job', 'Sales') THEN log.Timestamp ELSE NULL END) As Timestamp,
FROM log

现在的问题是当我尝试时:

SELECT Type,
       MAX(CASE WHEN log.Type IN ('Job', 'Sales') THEN log.Timestamp ELSE NULL END) As Timestamp,
       MAX(CASE WHEN log.Type IN ('Job', 'Sales') THEN log.UserID ELSE NULL END) As UserID,
FROM log

它根据字母顺序给我 max(userID),而不是基于 max(timeframe)..

当 TYPE = JOB 或 SALES 时,我需要 MAX(timeframe) 和对应的 UserID

(放置在包含许多其他列的大选择查询的末尾)。


示例查询更新:

这是我要执行的查询.. 非常抱歉我缺乏深入的知识!

DECLARE @FROMDATE AS DATETIME, @TODATE AS DATETIME;
SET @FROMDATE = '1 Mar 2013'; SET @TODATE = '31 Mar 2013';

SELECT CASE WHEN country.country_code IN (61,64,673,60,65,679,66,62,92,84,63,91) THEN 'APAC'
            WHEN country.country_code IN (81,82,852,853,886) THEN 'EAST ASIA'
            WHEN country.country_code IN (44,353,32,45,358,33,49,30,39,352,356,47,351,34,46,31) THEN 'EUROPE'
            WHEN country.country_code IN (1,101) THEN 'USA/CANADA' ELSE 'OTHER'
       END AS REGION,

       info.Status as STATUS, info.Code as CODE,
       CONVERT(VARCHAR, info.Start_Date,103) as 'START DATE', 

       log.Type AS TYPE,
       MAX(CASE WHEN log.Type IN ('Job','Sales') THEN log.Timestamp ELSE NULL END) As TIMESTAMP,   -- this works fine! :)
       MAX(CASE WHEN log.Type IN ('Job','Sales') THEN log.UserID ELSE NULL END) As USERID  --having trouble with this! :(

FROM log JOIN info ON (log.id = info.id), country

WHERE info.date BETWEEN @FROMDATE AND @TODATE
      AND info.Status NOT LIKE '%NA%'

GROUP BY country.code, info.status, info.code, info.start_date, log.type

我希望这对大家有所帮助,并再次感谢您的惊人支持。我猜这很简单,但我错过了一些东西..

【问题讨论】:

  • 您的最后一个查询应该可以工作,您是否收到任何错误消息?
  • 嗨,埃里克,感谢您的回复。最后一个查询没有给我任何记录(空白结果)。

标签: sql-server tsql select group-by max


【解决方案1】:

我根据您的问题创建了以下示例测试表:

CREATE TABLE Log (TYPE VARCHAR(5) NOT NULL, TIMESTAMP DATETIME NULL, USERID VARCHAR(3) NULL);

INSERT INTO Log
VALUES ('Job', '03/26/2013 00:24', 'DED'), ('Job', '03/21/2013 02:31', 'EGA'), ('Sales', NULL, NULL), ('Sales', NULL, NULL);

我尝试了您的最后一个示例查询,它工作正常。由于此查询对您不起作用,因此我编写了以下内容,它也应该可以处理并处理您有多行具有相同 TIMESTAMP 值的情况:

WITH BaseData
AS
    (SELECT *
        , ReverseOrder = ROW_NUMBER() OVER
            (ORDER BY TIMESTAMP DESC)
    FROM Log)
SELECT *
FROM BaseData
WHERE ReverseOrder = 1;

【讨论】:

  • 您好,这也很有效,喜欢添加订单列的想法。
  • 您好,这很好用,但我无法将它与多个表合并。我有多个表加入(所以事先有选择语句),并且需要选择 USERID 与 max(timestamp) where TYPE IN ('Job', 'Sales')..
  • 为了帮助解决上述问题-本质上,我想将其与我之前的 SELECT 语句和其他 WHERE 子句与来自其他表的 JOINS 结合起来。所以这一列(SELECT the USERID with the max(timestamp) where TYPE IN ('Job', 'Sales'))是我要创建的查询的最后一列..帮助! (谢谢!)
  • 如果您可以发布您的示例查询,那将会很有帮助。此外,您的原始代码“SELECT * FROM log WHERE timestamp = (SELECT max(timestamp) FROM log)”应该可以工作。你能提供一个创建表脚本和一个不返回任何内容的带有示例值脚本的插入吗?它没有意义。
【解决方案2】:

查看我对另一个问题的回答,以根据日期列获取表格中的第一行或最后一行:https://stackoverflow.com/a/10111071/452792

你可以试试:

DECLARE @FROMDATE AS DATETIME, @TODATE AS DATETIME;
SET @FROMDATE = '1 Mar 2013'; SET @TODATE = '31 Mar 2013';

;WITH LOG_CTE AS 
(
  SELECT Stuff(Max(Convert(Varchar, Timestamp, 20) + IsNull(Convert(Varchar, Id), '')), 1, 19, '') As Id
       , Max(Type) As Type
       , Max(timestamp) As Timestamp
       , Stuff(Max(Convert(Varchar, Timestamp, 20) + IsNull(Convert(Varchar, UserID), '')), 1, 19, '') As UserID
    FROM log 
   GROUP BY log.Type 
  HAVING log.Type IN ('JOB','SALES')
)
SELECT CASE WHEN country.country_code IN (61,64,673,60,65,679,66,62,92,84,63,91) THEN 'APAC'
            WHEN country.country_code IN (81,82,852,853,886) THEN 'EAST ASIA'
            WHEN country.country_code IN (44,353,32,45,358,33,49,30,39,352,356,47,351,34,46,31) THEN 'EUROPE'
            WHEN c.country_code IN (1,101) THEN 'USA/CANADA' ELSE 'OTHER'
       END AS REGION,

       info.Status as STATUS, info.Code as CODE,
       CONVERT(VARCHAR, info.Start_Date,103) as 'START DATE', 

       log.Type AS TYPE,
       log.Timestamp,
       log.UserID

FROM LOG_CTE log JOIN info ON (log.id = info.id)

WHERE info.date BETWEEN @FROMDATE AND @TODATE
      AND info.Status NOT LIKE '%NA%'

【讨论】:

  • Dominic,这是非常棒的,非常简单的解决方案。谢谢!
  • 嗨 Dominic,是否可以修改它以使用条件或 WHERE 子句检索?即我试图把它放在我的查询中:(SELECT Stuff(Max(Convert(Varchar, Timestamp, 20) + IsNull(Convert(Varchar, UserID), '')), 1, 19, '') FROM log WHERE log.Type IN ('JOB','SALES')) AS UserID 但这给了我很多重复的记录..
  • 如果您想要为每个TYPE 检索最后一个USERID,请使用GROUP BY/HAVINGSELECT Stuff(Max(Convert(Varchar, Timestamp, 20) + IsNull(Convert(Varchar, UserID), '')), 1, 19, '') FROM log group by log.type HAVING log.Type IN ('JOB','SALES')
  • 我想根据MAX(timestamp)检索USERID,以TYPE为条件。 TYPE 可能是('JOB' 或 'SALES').. 换种说法 - 我只想在输入('JOB','SALES')时出现MAX(timestamp) 时检索USERID。 。 我希望这是有道理的!再次感谢您。
  • 好的,然后试试SELECT Stuff(Max(Convert(Varchar, Timestamp, 20) + IsNull(Convert(Varchar, Case When log.Type IN ('JOB','SALES') Then UserID Else Null End), '')), 1, 19, '') FROM log。这将仅返回一行带有最后一个时间戳的用户 ID。如果类型不是工作或销售,它将返回 NULL 值。
猜你喜欢
  • 1970-01-01
  • 2017-03-11
  • 1970-01-01
  • 2020-07-06
  • 2015-01-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-05
相关资源
最近更新 更多