返回与相应MAX(日期时间)值相关的详细数据

时间:2013-03-26 18:18:49

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

我使用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

我想检索列TYPE,TIMESTAMP& USERID基于MAX(时间戳)..即结果应为

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 USERID MAX(timestamp) WHERE TYPE`可以等于('Job'或'销售')..

我发现这完美无缺:

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(时间帧)..

当TYPE = JOB或SALES

时,我需要MAX(时间帧)和相应的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

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

2 个答案:

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

答案 1 :(得分:1)

根据日期列查看我在另一个问题上的答案,以获取表格中的第一行或最后一行: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%'