同一张表中的两个JOINS

时间:2018-12-26 20:20:31

标签: sql sql-server

我有两个表文档外部参照

外部参照是一种将文档链接到另一个文档的方法。

外部参照表存储文档 t的 id (来自文档表),并且已链接外部参照 >(同样来自文档表)

我想为链接到特定文档外部参照检索文件名的列表。

请参阅附件中的表格的基本图片。

以下SQL语句检索我想要的(xref)文件名,但我希望能够使用文件名而不是其ID来检索它。

任何帮助将不胜感激。谢谢。

enter image description here

5 个答案:

答案 0 :(得分:2)

针对Xref两次,一次获取参考文件的文件名,一次搜索主文档的文件名

SELECT d2.filename
FROM Document d
JOIN Xref x ON d.id = x.document_id
JOIN Document d2 ON d2.id = x.xref_id
WHERE d.name = ?

例如

SELECT d2.filename
FROM Document d
JOIN Xref x ON d.id = x.document_id
JOIN Document d2 ON d2.id = x.xref_id
WHERE d.name = 'D001'

返回

  

文件名
  X001

答案 1 :(得分:1)

您需要加入两个表。这应该做到:

SELECT d.filename
FROM 
    Document d
    INNER JOIN Xref x ON x.xref_id = d.id
WHERE x.document_id = ?

您要用要查找其文件名的文档ID替换问号。

如果要按文档名称而不是文档ID进行搜索,则需要再加入一个JOIN:

SELECT d.filename
FROM 
    Document d
    INNER JOIN Xref x ON x.xref_id = d.id
    INNER JOIN Document d2 ON d2.id = x.document_id
WHERE d2.filename = ?

NB:这假设每个文档在表Xref中都有一个链接的文档。如果不想在没有外部参照的情况下过滤掉文档,则要使用“ <左联接”»而不是““内联接”»。

答案 2 :(得分:0)

您需要选择主数据,然后在某些字段或列上使用JOIN。

LEFT JOIN将保留来自左组的数据。

INNER JOIN仅与比赛结果匹配。

需要确保文件名是否唯一?反正

如果要使用LEFT JOIN来使左数保持为空值,请使用:

SELECT DOCUMENT.filename FROM Xref XREF
LEFT JOIN Document DOCUMENT ON XREF.document_id = DOCUMENT.id
-- Filter by filename:
--WHERE DOCUMENT.filename = ? OR XREF

否则,我建议选择INNER JOIN以获得匹配的行:

SELECT DOCUMENT.filename FROM Xref XREF
INNER JOIN Document DOCUMENT ON XREF.document_id = DOCUMENT.id
-- Filter by filename:
--WHERE DOCUMENT.filename = ?

结果:
|文件名|
| D001 |
| D002 |

SELECT * FROM-将显示所有列,您需要定义将在新视图中显示的列。

编辑 关于您的评论,假设您有两个输入选项,可以使用:

SELECT DOCUMENT.filename FROM Xref XREF
INNER JOIN Document DOCUMENT ON XREF.document_id = DOCUMENT.id
-- Filter by filename:
WHERE DOCUMENT.filename = ? XREF.id = ?

答案 3 :(得分:0)

其他解决方案适用于单级搜索。如果您想进行多级搜索,可以使用CTE,前提是数据中没有循环:

with
x as (
  select id, filename from document where filename = 'mydoc1.txt'
  union all
  select d.id, d.filename
  from x
  join xref r on r.document_id = x.id
  join document d on d.id = r.xref_id
)
select * from x;

答案 4 :(得分:0)

如果要保留没有子文档的文档,请使用LEFT OUTER JOIN获取所有主文档。

此外,我使用子选择将子文档链接到xref表,然后将其链接回到主文档查询。

SELECT d1.id AS main_docid, d1.filename AS main_filename
    , s1.sub_docid AS sub_docid, s1.sub_filename AS sub_filename
FROM document d1 
LEFT OUTER JOIN (
    SELECT x.document_id AS main_docid 
        , d2.id AS sub_docid
        , d2.filename AS sub_filename
    FROM xref x 
    INNER JOIN document d2 ON x.xref_id = d2.id
) s1 ON d1.id = s1.main_docid
WHERE d1.filename = ??????? /* Whatever filename you are searching for. */

如果要按sub_filename搜索,则将WHERE语句更改为WHERE s1.sub_filename = ???????