【问题标题】:sql join within join?sql连接内连接?
【发布时间】:2011-03-16 04:01:59
【问题描述】:

我需要你的帮助来构建一个我无法理解的 SQL 语句。

在数据库中,我有四个表 - 文件、文件夹、文件夹文件和链接。

我有很多文件。其中之一称为“myFile.txt”。

我有很多文件夹。 “myFile.txt”在其中一些。它出现的第一个文件夹称为“firstFolder”。

我有许多指向许多文件夹的链接。 “firstFolder”的第一个链接称为“firstLink”。

示例的数据结构是:

// files
Id: 10
Name: "myFile.txt"

// folders
Id: 20
Name: "firstFolder"

// folder_files (join table)
Id: 30
Folder_Id: 20 (meaning "firstFolder")
File_Id: 1 (meaning "myFile.txt")

// links
Id: 40
Name: "firstLink"
Folder_Id: 20 (meaning "firstFolder")

第一个问题:如何根据文件夹的最低 ID 和链接?

第二个问题:如何获取“myFile.txt”的记录以及“firstLink”(第一个链接)的名称和 ID,根据文件夹和链接的最低 ID 查询所有文件?

换一种说法 - 如何获得第一个指向包含“myFile.txt”的文件夹的第一个链接?

生成如下所示的记录:

Id: 10
Name: "myFile.txt"
LinkId: 40
LinkName: "firstLink"

谢谢!

【问题讨论】:

  • “第一”是指ID最低的吗?
  • 我添加了标签greatest-n-per-group。尝试单击该标签,您会看到许多其他类似问题的案例以及解决方案。尝试阅读其中的一些内容,然后返回并用您尝试过的内容编辑您的问题(最好自己做作业)。抱歉,我不得不蚕食你的 subselect 标签,因为标签限制为五个。但是你不一定需要子选择来解决这个问题。
  • @Wrikken - 是的,最低 ID。 @bill - 感谢您的编辑,尽管我是 SQL 新手,但我真的不知道每个组中最伟大的 n 组之间的关系如何?我想我只是在做连接......?在发布之前,我在这个论坛和网络上搜索了一个小时。

标签: sql mysql join greatest-n-per-group


【解决方案1】:

考虑到:

  • 每个文件有更多文件夹
  • 每个文件夹有更多链接
  • 以最低 id 文件夹为链接,以最低 id 链接为文件夹

借助:mysql: group by ID, get highest priority per each ID

文件表中所有文件的答案(选择JohnB的单个文件解决方案,它会更快):

SELECT file_id, file_name, link_id, link_name FROM (
SELECT file_id, file_name, link_id, link_name,
    @r := CASE WHEN @prev_file_id = file_id
                    THEN @rn + 1
                    ELSE 1
               END AS r,
    @prev_file_id := file_id
FROM (
    SELECT
        f.id as file_id, f.name as file_name, l.id as link_id, l.name as link_name
    FROM files f
    JOIN folder_files ff
    ON ff.file_id = f.id
    JOIN links l
    ON l.folder_id = ff.folder_id
    ORDER BY ff.folder_id, l.id -- first folder first, first link to first folder second
) derived1,
(SELECT @prev_file_id := NULL,@r:=0) vars
) derived2
WHERE r = 1;

【讨论】:

    【解决方案2】:

    您应该尝试考虑您希望结果集的外观。 SQL 旨在描述结果集。如果您可以写出假设的结果集,您可能会更轻松地编写将呈现该结果集的 SQL。

    我很难理解您在寻找什么,但我敢肯定这是一个相当直截了当的问题。如果您能更清楚地描述您的结果,我将能够更轻松地为您提供帮助,尽管您可能不再需要我的帮助!

    例如(与您一起使用原始架构)Q1 和 Q2:

    files.Id, files.Name, links.Id, links.Name(4 列)

    第一季度:

    SELECT
      files.Id, files.Name, links.Id, links.Name
    FROM
      files, links
    INNER JOIN
      folder_files
      ON files.Id = folder_files.File_Id
    INNER JOIN
      links
      ON links.Id = folder_files.Folder_Id
    WHERE
      files.Id = 10
    ORDER BY
      folder_files.File_Id ASC, links.Id ASC
    LIMIT 1;

    JOIN 不需要文件夹表)

    第二季度:

    ASC 都更改为DESC

    【讨论】:

    • 谢谢 - 我在发布后不久就想到了这一点,但它没有出现在我的编辑中。它现在就在那里。
    • 就是这样!两个内连接!这就是我所缺少的。谢谢!
    【解决方案3】:

    我会试试这个:

    select f.*
            , l.Id as LinkId
            , l.Name as LinkName, 
        from Link l
            inner join Folder_Files ff on ff.Folder_Id = l.Folder_Id
            inner join Files f on f.Id = ff.File_Id
        where f.Id = 10
    

    导致:

     Id | Name       | LinkId | LinkName
     10 | myFile.txt | 40     | firstLink
    

    这是你想要的吗?

    【讨论】:

      【解决方案4】:

      这会选择文件 id 10 的所有链接:

      select links.id, links.name
       from files
       left join folder_files on files.id = folder_files.file_id
       left join folders on folder_files.folder_id = folders.id
       left join links on links.folder_id = folders.id
       where files.id=10;
      

      更改 where 子句,为您想要的其他内容添加限制或任何内容。修改这个应该很简单。

      【讨论】:

      • 抱歉,我的问题措辞有误。我想获取链接的名称和 ID,以及文件的记录数据。所以它们不是单独的查询。
      猜你喜欢
      • 1970-01-01
      • 2015-03-09
      • 1970-01-01
      • 2022-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-25
      • 1970-01-01
      相关资源
      最近更新 更多