我有一个postgres数据库,其中包含用户表(userid,firstname,lastname)和usermetadata表(userid,代码,内容,创建的日期时间)。 我按代码在usermetadata表中存储有关每个用户的各种信息,并保留完整的历史记录。 例如,用户(用户ID 15)具有以下元数据:

15, 'QHS', '20', '2008-08-24 13:36:33.465567-04'  
15, 'QHE', '8', '2008-08-24 12:07:08.660519-04'  
15, 'QHS', '21', '2008-08-24 09:44:44.39354-04'  
15, 'QHE', '10', '2008-08-24 08:47:57.672058-04'  

我需要获取所有用户的列表以及各种用户元数据代码的最新值。 我以编程方式做到了这一点,当然是神圣的缓慢。 在SQL中我能想到的最好的方法是加入子选择,这也很慢,我必须为每个代码做一个。

===============>>#1 票数:6

这在PostgreSQL中实际上并不难,因为它的SELECT语法中有“DISTINCT ON”子句(DISTINCT ON不是标准SQL)。

SELECT DISTINCT ON (code) code, content, createtime
FROM metatable
WHERE userid = 15
ORDER BY code, createtime DESC;

这会将返回的结果限制为每个唯一代码的第一个结果,如果按创建时间降序对结果进行排序,则会获得每个结果的最新结果。

===============>>#2 票数:1 已采纳

我想你不愿意修改你的架构,所以我担心我的回答可能没什么帮助,但是这里......

一种可能的解决方案是,当您插入“弃用日期”时,将时间字段设置为空,直到它被更新的值替换。 另一种方法是使用“活动”列扩展表,但这会引入一些冗余。

经典的解决方案是同时具有“Valid-From”和“Valid-To”字段,其中“Valid-To”字段为空,直到其他条目变为有效。 这可以通过使用触发器或类似方法轻松处理。 使用约束来确保每种类型只有一个有效的项目将确保数据的完整性。

这些的共同点是有一种确定当前字段集的方法。 您只需选择活动用户的所有条目以及NULL“有效期”或“弃用日期”或真正的“有效”。

您可能有兴趣查看关于时态数据库的Wikipedia条目和时间数据库概念的共识词汇表

===============>>#3 票数:0

子选择是执行此类操作的标准方法。 您只需要在UserId,代码和日期上使用唯一约束 - 然后您可以运行以下命令:

SELECT * 
FROM Table
JOIN (
   SELECT UserId, Code, MAX(Date) as LastDate
   FROM Table
   GROUP BY UserId, Code
) as Latest ON
   Table.UserId = Latest.UserId
   AND Table.Code = Latest.Code
   AND Table.Date = Latest.Date
WHERE
   UserId = @userId

  ask by adambox translate from so

未解决问题?本站智能推荐: