关系数据库查询问题

时间:2011-05-18 20:39:45

标签: sql database postgresql set

我有一个关于我想针对PostgreSQL表执行的特定查询的问题。虽然我欢迎批评我使用的表格方案,但我会更加欣赏我实际问题的答案!

我正在使用uuid-ossp postgresql-contrib模块并具有以下表结构:

       Column        |            Type             | Modifiers | Storage  | Description
---------------------+-----------------------------+-----------+----------+-------------
 revision_id         | uuid                        | not null  | plain    |
 document_id         | uuid                        | not null  | plain    |
 user_id             | uuid                        | not null  | plain    |
 datetime_edited     | timestamp without time zone | not null  | plain    |
 contents            | text                        | not null  | extended |
Indexes:
    "document_pkey" PRIMARY KEY, btree (revision_id)

这个想法是:

  • 文档可能包含一个或多个修订版。修订不会被删除。为了更新文档,我们插入了一个新行,其中包含一个新的revision_id但相同的document_id
  • revision_id在所有文档的修订版中都是唯一的。
  • contents是代表文档的数据blob,user_id标识谁更新了文档。

我正在努力想出一个查询,该查询返回特定用户创建的所有文档的所有最新版本。我知道我能做到,例如:

select * from document where user_id = '6a2aabc417b34ef99b14b10eaa8e9313';

但这会返回所有文件。如何向下钻取并按document_idLIMIT 1请求分组,并根据revision_id返回最新的datetime_edited

编辑:由于文档可以有一个或多个修订版,因此“用户创建的所有文档 ”一直模糊不清。通过创建我的意思是用户已经对文档进行了一次或多次修订,即至少有一个用户编辑文档的修订版。

这样的事情在一个查询中是否可以实现,或者我是否需要多次访问数据库才能实现这一目标?

编辑:revision_id不是单调增加的。这是一个随机的UUID。因此,max(revision_id)!= max(datetime_edited)。

2 个答案:

答案 0 :(得分:2)

获取每个文档的最高版本ID,然后选择这些文档:

select *
from document
where revision_id in (
  select max(revision_id)
  from document
  where user_id = '6a2aabc417b34ef99b14b10eaa8e9313'
  group by document_id
)

更新

由于版本ID不是增量版,您必须选择document_id并且它是最新的datetime_edited,并加入文档表:

select d.*
from document d
inner join (
  select document_id, max(datetime_edited) as datetime_edited
  from document
  where user_id = '6a2aabc417b34ef99b14b10eaa8e9313'
  group by document_id
) x on x.document_id = d.document_id and x.datetime_edited = d.datetime_edited

答案 1 :(得分:2)

Select ...
From document As D
    Join    (
            Select D1.document_id, Max( datetime_edited ) As datetime_edited
            From document As D1
            Group By D1.document_id
            ) As LastRevision
        On LastRevision.document_id = D.document_id
            And LastRevision.datetime_edited = D.datetime_edited
Where Exists    (
                Select 1
                From document As D2
                Where D2.document_id = D.document_id
                    And D2.user_id = '6a2aabc417b34ef99b14b10eaa8e9313'
                )

另一种形式:

Select ...
From document As D
    Join    (
            Select D1.document_id, Max( datetime_edited ) As datetime_edited
            From document As D1
            Group By D1.document_id
            ) As LastRevision
        On LastRevision.document_id = D.document_id
            And LastRevision.datetime_edited = D.datetime_edited
    Join    (
            Select D2.document_id
            From document As D2
            Where D2.user_id = '6a2aabc417b34ef99b14b10eaa8e9313'
            Group By D2.document_id
            ) As UserDocs
        On UserDocs.document_id = D.document_id