正在构建一个文档管理器,其中一个文件可以属于多个文件夹(当从前端执行复制操作时)和一个文件夹同样属于多个文件,同时要记住一个文件和文件夹可以属于到了另一个文件夹。随着这个设计,我选择了多对多的关系,因为这很有意义。我有三个表文件夹,文件,file_folder,其中file_folder是数据透视表。
My Simple DB Schema定义如下:
文件:
file_id | name
1 | document.docx
文件夹:
folder_id | name
1 | root
2 | images
file_folder:
file_id | folder_id | phash
NULL | 2 | 1
1 | NULL | 1
现在的问题是,我一直在尝试编写一个连接查询,如果它们共享同一个文件夹,则返回两个文件和文件夹的列表,下面是我尝试但没有一个能够返回的查询列表期望的结果。
我非常想要这样的结果:
file_id | folder_id | name
1 | NULL | document.docx
NULL | 2 | images
SELECT * FROM
folders dir
JOIN file_folder dir_file
ON dir_file.dir_id = dir.dir_id
JOIN files file
ON dir_file.file_id = file.file_id
WHERE dir_file.dir_id = 1 ORDER BY dir_file.created_at
SELECT * FROM
folders dir,files file
JOIN file_folder dir_file
ON (dir_file.file_id = file.file_id OR dir_file.dir_id = dir.dir_id)
WHERE dir_file.dir_id = 1 ORDER BY dir_file.created_at
我知道我只是遗漏了一些东西,我还不知道。或许我只是让DB Schema完全错误。我真的不想把文件和文件夹放在同一个桌子上并引用phash(父文件夹),这样可行,但是将文件夹复制到另一个文件夹只会复制文件夹而不是文件里面的文件,因为我将不得不复制所有子文件夹和文件,以实现这一点,这是非常糟糕的。如果我能得到一个解决方案,我将不胜感激
编辑:
以下对我来说工作正常!
SELECT * FROM folders dir
LEFT JOIN file_folder dir_file
ON dir_file.dir_id = dir.dir_id
LEFT JOIN files file
ON dir_file.file_id = file.file_id
WHERE dir_file.phash = 1 ORDER BY dir_file.created_at
答案 0 :(得分:1)
由于您在表格之间并不总是匹配,因此您应该使用左连接
SELECT *
FROM folders dir
LEFT JOIN file_folder dir_file ON dir_file.dir_id = dir.dir_id and dir_file.phash = 1
LEFT JOIN files file ON dir_file.file_id = file.file_id
ORDER BY dir_file.created_at
在左连接中移动On子句中的where条件(否则用作内连接)