4

我正在设计表格,其中将包含一些随时间变化的对象的属性。

CREATE TABLE [dbo].[ObjectProperties]
(
    [Id] INT NOT NULL PRIMARY KEY IDENTITY, 
    [ObjectType] SMALLINT NOT NULL, 
    [Width] SMALLINT NOT NULL, 
    [Height] SMALLINT NOT NULL, 
    [Weight] SMALLINT NOT NULL
)

假设我有这个 ObjectTypes:1 = 椅子 2 = 桌子

该表的数据:

INSERT INTO [dbo].[ObjectProperties] ([Id], [ObjectType], [Width], [Height], [Weight]) VALUES (1, 1, 50, 50, 1000)
INSERT INTO [dbo].[ObjectProperties] ([Id], [ObjectType], [Width], [Height], [Weight]) VALUES (2, 2, 80, 40, 500)
INSERT INTO [dbo].[ObjectProperties] ([Id], [ObjectType], [Width], [Height], [Weight]) VALUES (3, 1, 50, 50, 2000)

所以,正如你所看到的,我有一个重量为 1000 的椅子对象,然后我将重量更改为 2000。我正在存储诸如对象属性的修改历史之类的东西。现在我想从这个表中为每个对象选择最新的数据。我知道如何为每个对象一一选择最新数据:

SELECT TOP 1 * FROM [ObjectProperties] WHERE ObjectType = 1 ORDER BY Id DESC

但是如果我想用一个查询选择几个对象呢?喜欢

SELECT ... * FROM [ObjectProperties] WHERE ObjectType IN (1, 2) ...

并接收 id 为 2 和 3 的行(因为 3 的椅子属性比 1 新)

4

2 回答 2

4

您可以使用具有ROW_NUMBER排名功能的 CTE:

WITH CTE AS(
    SELECT *, 
       RN=ROW_NUMBER()OVER(PARTITION BY ObjectType ORDER BY ID DESC)
    FROM [ObjectProperties] op
)
SELECT * FROM CTE WHERE RN = 1
AND ObjectType IN (1, 2)

演示

每个-group order byROW_NUMBER返回一行(因此具有最高 ID 的记录)。如果您想按某些 ID 进行过滤,您只需在 CTE 或外部应用适当的子句。ObjectTypeID DESCWHERESELECT

排名函数

于 2013-07-17T10:57:50.283 回答
3

一个简单(诚然粗略)的方法如下:

select * from ObjectProperties where id in
   (select max(id) from ObjectProperties group by objecttype)

这给出了:

Id          ObjectType Width  Height Weight
----------- ---------- ------ ------ ------
2           2          80     40     500
3           1          50     50     2000
于 2013-07-17T10:59:58.603 回答