不知道如何编写复杂的 SQL 查询
-
12-09-2019 - |
题
我有以下数据库结构:
文件、用户、FileRevision(具有文件的外键,以及通过中间表到用户的多对多连接)。
我想获取所有 FileRevision-s:
- 在其相应的文件中是最新的/最新的,
- 与执行搜索(权限检查)的用户有多对多链接。
我发现我可以通过执行以下操作来做到(1):
SELECT created_on, file_id FROM FileRevision
WHERE created_on = (SELECT MAX(created_on) FROM FileRevision
WHERE filed_id = file_id)
但我不知道如何同时执行 m2m 权限检查
解决方案
这是“每组最大 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 替换为“?
".
其他提示
只需将其添加到您的查询中:
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
您将避免相关(重复)子查询。
要检查权限,您需要检查请求文件的用户的其他多对多权限表中是否存在记录。因此添加一个 And/OR Exists 子句...如果您只想(正如我怀疑的那样)请求者有权访问的最后一个修订版,请使用 AND。
如果您希望请求者有权访问最后的修订版和记录,请使用 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 = ?)
不隶属于 StackOverflow