如何根据日期字段选择不同的数据?

| 我有一个表,用于存储另一个表中对象的更改日志。这是我的表格内容:
ObjID   Color   Date                     User
------- ------- ------------------------ --------
1       Red     2010-01-01 12:22:00.000  Joe
1       Blue    2010-01-02 15:22:00.000  Jill
1       Green   2010-01-03 16:22:00.000  Joe
1       White   2010-01-10 09:22:00.000  Mike
2       Red     2010-01-09 10:22:00.000  Mike
2       Blue    2010-01-12 09:22:00.000  Jill
2       Orange  2010-01-12 15:22:00.000  Joe
我想选择每个对象的最新日期,以及该记录日期的颜色和用户。 基本上,我想要这个结果集:
ObjID   Color   Date                     User
------- ------- ------------------------ --------
1       White   2010-01-10 09:22:00.000  Mike
2       Orange  2010-01-12 15:22:00.000  Joe
我在为获取此数据而需要写的SQL查询上遇到麻烦... 我正在通过ODBC从iSeries DB2数据库(AS / 400)检索数据。     
已邀请:
嘿,我想您需要以下内容(其中ColorTable是表名):
SELECT Color.* 
FROM ColorTable as Color
INNER JOIN 
(
SELECT ObjID, MAX(Date) as Date
FROM ColorTable
GROUP BY ObjID
) as MaxDateByColor
ON Color.ObjID = MaxDateByColor.ObjID
AND Color.Date = MaxDateByColor.Date 
    
假设至少是SQL Server 2005
DECLARE @T TABLE (ObjID INT,Color VARCHAR(10),[Date] DATETIME,[User] VARCHAR(50))

INSERT INTO @T
SELECT 1,\'Red\',\' 2010-01-01 12:22:00.000\',\'Joe\' UNION ALL
SELECT 1,\'Blue\',\'2010-01-02 15:22:00.000\',\'Jill\' UNION ALL
SELECT 1,\'Green\',\' 2010-01-03 16:22:00.000\',\'Joe\' UNION ALL
SELECT 1,\'White\',\' 2010-01-10 09:22:00.000\',\'Mike\' UNION ALL
SELECT 2,\'Red\',\' 2010-01-09 10:22:00.000\',\'Mike\' UNION ALL
SELECT 2,\'Blue\',\'2010-01-12 09:22:00.000\',\'Jill\' UNION ALL
SELECT 2,\'Orange\',\'2010-01-12 15:22:00.000\',\'Joe\'

;WITH T AS
(
SELECT *,
       ROW_NUMBER() OVER (PARTITION BY ObjID ORDER BY Date DESC) AS RN
FROM @T
)
SELECT ObjID,
       Color,
       [Date],
       [User]
FROM T 
WHERE RN=1
或注释中链接到的文章中的SQL Server 2000方法
SELECT ObjID,
  CAST(SUBSTRING(string, 24, 33) AS VARCHAR(10)) AS Color,
  CAST(SUBSTRING(string,  1, 23) AS DATETIME ) AS [Date],
  CAST(SUBSTRING(string, 34, 83) AS  VARCHAR(50)) AS [User]
FROM 
(
SELECT ObjID, 
          MAX((CONVERT(CHAR(23), [Date], 126)
         + CAST(Color AS CHAR(10))
         + CAST([User] AS CHAR(50))) COLLATE Latin1_General_BIN) AS string
FROM @T
GROUP BY ObjID) T;
    
如果您有一个Objects表,而ObjectHistory表有一个ObjID和date的索引,那么这可能比到目前为止给出的其他查询更好:
SELECT
   X.*
FROM
   Objects O
   CROSS APPLY (
      SELECT TOP 1 *
      FROM ObjectHistory H
      WHERE O.ObjID = O.ObjID
      ORDER BY H.[Date] DESC
   ) X
仅当您也从Objects表中拉出列时,性能才会提高,但这值得一试。 如果想要所有对象而不管它们是否具有历史记录条目,请切换到
OUTER APPLY
(当然,请使用
O.ObjID
而不是
H.ObjID
)。 关于此查询的整洁之处在于 它解决了Date值可以重复的情况 每个组可以支持任意数量的项目(例如,前5名代替前1名)     
请参阅以下两个相关问题: SQL / mysql-选择唯一/唯一,但返回所有列? 和: 如何使用SQL有效地确定行之间的更改     
SELECT t1.* FROM Table_name as t1
INNER JOIN (
  SELECT MAX(Date) as MaxDate, ObjID FROM Table_name
  GROUP BY ObjID
) as t2
ON t1.ObjID = t2.ObjID AND t1.Date = t2.MaxDate
    
您可以按对象找到每个对象的最新更改,如下所示:
        select objectid, max(changedate) as LatestChange
        from LOG
        group by objectid
然后,您可以通过将上面返回的集合(链接为实例化为已被赋予别名的内联视图实例化)再次链接到同一张表来获得color和user列:
       select color, user, FOO.objectid, FOO.LatestChange
       from LOG
       inner join
       (

          select objectid, max(changedate) as LatestChange
        from LOG
        group by objectid


        ) as FOO
        on LOG.objectid = FOO.objectid and LOG.changedate = FOO.LatestChange
    
就像上面的马丁·史密斯 只需在分区上做一个行号,然后选择最近的行之一 喜欢
SELECT  Color,Date,User
FROM (
   SELECT *,
          ROW_NUMBER() OVER (PARTITION BY User ORDER BY [DATE]) AS ROW_NUMBER
   FROM [tablename]
   ) AS ROWS
WHERE 
ROW_NUMBER = 2
    

要回复问题请先登录注册