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

发布于 2024-11-09 18:02:28 字数 841 浏览 6 评论 0原文

我有一个表,用于存储另一个表中对象的更改日志。以下是我的表格内容:

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) 检索数据。

I have table that stores a log of changes to objects in another table. Here are my table contents:

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

I want to select the most recent date for each Object, as well as the Color and User on the date of that record.

Bascically, I want this result set:

ObjID   Color   Date                     User
------- ------- ------------------------ --------
1       White   2010-01-10 09:22:00.000  Mike
2       Orange  2010-01-12 15:22:00.000  Joe

I'm having trouble wrapping my head around the SQL query I need to write to get this data...

I am retrieving data via ODBC from an iSeries DB2 database (AS/400).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

极度宠爱 2024-11-16 18:02:28

嘿,我想您想要以下内容(其中 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 

Hey there, I think you want the following (where ColorTable is your table name):

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 
花落人断肠 2024-11-16 18:02:28

假设至少有 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;

Assuming at least 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

Or a SQL Server 2000 method from the article linked to in the comments

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;
半葬歌 2024-11-16 18:02:28

如果您有一个对象表,并且您的 ObjectHistory 表在 ObjID 和日期上有一个索引,那么这可能比迄今为止给出的其他查询执行得更好:

SELECT
   X.*
FROM
   Objects O
   CROSS APPLY (
      SELECT TOP 1 *
      FROM ObjectHistory H
      WHERE O.ObjID = O.ObjID
      ORDER BY H.[Date] DESC
   ) X

只有当您也从对象表中提取列时,性能改进可能才会出现,但是值得一试。

如果您想要所有对象,无论它们是否有历史记录条目,请切换到OUTER APPLY(当然使用O.ObjID而不是H.ObjID)代码>)。

这个查询的巧妙之处在于

  1. 它解决了日期值可能有重复的情况
  2. 它可以支持每组任意数量的项目(例如,前 5 个而不是前 1 个)

If you have an Objects table and your ObjectHistory table has an index on ObjID and date, then this could perform better than other queries given so far:

SELECT
   X.*
FROM
   Objects O
   CROSS APPLY (
      SELECT TOP 1 *
      FROM ObjectHistory H
      WHERE O.ObjID = O.ObjID
      ORDER BY H.[Date] DESC
   ) X

The performance improvement may only come if you're pulling columns from the Objects table, too, but it's worth a shot.

If you want all Objects regardless of whether they have a history entry, switch to OUTER APPLY (and of course use O.ObjID instead of H.ObjID).

The neat thing about this query is that

  1. It solves for situations where the Date value can have duplicates
  2. It can support an arbitrary number of items per group (say, the top 5 instead of the top 1)
百合的盛世恋 2024-11-16 18:02:28
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 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
溺渁∝ 2024-11-16 18:02:28

您可以找到每个对象的最新更改,如下所示:

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

然后,您可以通过将上面返回的集(实例化为已指定别名的内联视图)再次链接到同一个表来获取颜色和用户列:

       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

You can find out, per object, its most recent change like this:

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

You can then get the color and user columns by linking the set returned above, instantiated as an inline view that has been given an alias, to the same table again:

       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
因为看清所以看轻 2024-11-16 18:02:28

就像上面的马丁·史密斯一样,
只需在分区上输入行号并选择最新的行之一
喜欢

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

like martin smiths above,
simply just do a row number over partition and pick one of the rows that is most recent
like

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文