2

我有以下数据库结构:

File、User、FileRevision(具有 File 的外键,以及通过中间表到 User 的多 2 多连接)。

我想获取所有 FileRevision-s:

  1. 在其相应的 File-s 中是最新/最新的,
  2. 具有指向执行搜索的用户的多对多链接(权限检查)。

我发现我可以通过执行以下操作来做到(1):

SELECT created_on, file_id FROM FileRevision
WHERE created_on = (SELECT MAX(created_on) FROM FileRevision
                    WHERE filed_id = file_id)

但我不知道如何同时执行 m2m 权限检查

4

3 回答 3

2

这是“greatest-n-per-group”问题的一种变体。这是我在没有子查询和 no 的情况下解决它的方法GROUP BY

SELECT f1.*
FROM Permissions p -- this is the many-to-many table
JOIN FileRevision f1
  ON (f1.file_id = p.file_id)
LEFT OUTER JOIN FileRevision f2 
  ON (f2.file_id = p.file_id AND f1.created_on < f2.created_on)
WHERE p.user_id = ? AND f2.file_id IS NULL;

将所需的用户 ID 替换为“ ?”。

于 2009-09-20T16:11:36.907 回答
1

只需将其添加到您的查询中:

UNION
SELECT created_on, file_id
FROM FileRevision fr
WHERE fr.user_id = ?

代替 ?根据您的权限检查,使用您想要的任何值。

此外,如果您将查询替换为:

SELECT created_on, file_id 
FROM FileRevision fr 
  JOIN 
  (
    SELECT file_id, MAX(created_on) as latestDate 
    FROM FileRevision 
    GROUP BY file_id
  ) latest ON latest.file_id = fr.file_id 
           AND latest.latestDate = fr.created_on

您将避免相关(重复)子查询。

于 2009-09-20T12:16:29.373 回答
1

要检查权限,您需要检查请求文件的用户的其他多对多权限表中是否存在记录。所以添加一个 And/OR Exists 子句...如果您(我怀疑)只想要请求者有权访问的最后一个修订版,请使用 AND。

如果您想要最后一个 Rev 和请求者有权访问的记录,请使用 OR。

SELECT created_on, file_id 
FROM FileRevision r
WHERE created_on = 
    (SELECT MAX(created_on) 
     FROM FileRevision                    
     WHERE file_id = r.file_id)
  And Exists       --  Change 'And' to 'Or if you want both
     (Select * From M2MIntermediatePermissionsTable
      Where File_Id = r.File_Id
          And userId = ?)
于 2009-09-20T12:28:05.327 回答