2009-09-20 40 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