代码之家  ›  专栏  ›  技术社区  ›  Tomasz Zieliński

不知道如何编写复杂的SQL查询

  •  2
  • Tomasz Zieliński  · 技术社区  · 16 年前

    我有以下数据库结构:

    文件、用户、文件修订版(具有到文件的外键,以及通过中间表到用户的多对多连接)。

    我要获取所有文件revision-s:

    1. 在相应的文件中是最新的/最新的,
    2. 与执行搜索(权限检查)的用户有多个多链接。

    我发现我可以通过执行以下操作来完成:

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

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

    3 回复  |  直到 16 年前
        1
  •  2
  •   Bill Karwin    16 年前

    这是“最大每组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替换为“ ? “。

        2
  •  1
  •   CMerat    16 年前

    只需将此添加到查询中:

    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
    

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

        3
  •  1
  •   Charles Bretana    16 年前

    要检查Permissions,您需要检查一个记录是否存在于请求文件的用户的其他many-2-many权限表中。所以添加一个和/或exists子句… 如果您(我怀疑)只需要请求者有权访问、使用和的最后一次修订。

    如果您想要最后一个版本和请求者可以访问、使用或的记录。

    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 = ?)