我需要你帮助构建一个我无法解决的SQL语句。
在数据库中,我有四个表 - 文件,文件夹,folders_files和链接。
我有很多文件。其中一个叫做“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")
第一个问题:我如何获取“myFile.txt”的记录以及“firstLink”的名称和ID(第一个链接),根据文件夹的最低Id和文件ID = 10查询文件ID = 10链路?
第二个问题:我如何获取“myFile.txt”的记录和“firstLink”(第一个链接)的名称和ID,查询所有文件,基于文件夹和链接的最低ID?
换句话说 - 如何获得包含“myFile.txt”的第一个文件夹的第一个链接?
导致记录如下:
Id: 10
Name: "myFile.txt"
LinkId: 40
LinkName: "firstLink"
谢谢!
答案 0 :(得分:2)
您应该尝试考虑您希望结果集的外观。 SQL旨在描述结果集。如果您可以写出假设的结果集,那么您可以更轻松地编写将呈现该结果集的SQL。
我很难理解你在寻找什么,但我确信这是一个相当直接的问题。如果您可以更清楚地描述结果,我将能够帮助您更轻松,尽管您可能不再需要我的帮助了!
例如(与您一起使用原始架构)Q1& Q2:
files.Id, files.Name, links.Id, links.Name
(4栏)
Q1:
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
不需要文件夹表)
Q2:
将ASC
更改为DESC
答案 1 :(得分:1)
这将选择文件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子句,添加限制或其他任何内容。修改它应该很简单。
答案 2 :(得分:0)
我会试试这个:
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
这是你想要的吗?
答案 3 :(得分:0)
考虑到:
借助: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;