2009-09-20 38 views
2

我有以下数据库结构:不知道如何编写复杂的SQL查询

文件,用户FileRevision(有外键文件,并通过中间表中的许多-2-许多连接到用户)。

我想获取所有FileRevision-S说:

  1. 是最新在其相应的文件-S /新鲜,
  2. 有很多-2-许多链接,用户执行搜索(权限检查) 。

我发现我可以通过执行像做(1):

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

,但我不知道如何同时还执行M2M权限检查

回答

2

这是“最大n组”问题的变体。以下是我没有子查询解决它,并没有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。

+0

这个答案是我的最爱+ JOIN序列在我看来是复杂查找的有力武器。 – 2009-09-22 18:44:00

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 

你会避免相关(重复)子查询。

+0

谢谢,我主要采用了Bill Karwin的解决方案,但这也向我展示了一些新的SQL技巧。 – 2009-09-22 18:40:05

1

要检查permsissions,您需要检查记录是否存在于请求文件的用户的其他many-2-many权限表中。因此,添加一个和/或存在的条款... 如果你想(只要我怀疑)只有请求者有权访问的最后一个版本,请使用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 = ?) 
+0

谢谢Exists +中级表选择非常有用! – 2009-09-22 18:41:21