我正在尝试联接三个表,并显示子查询中列出的两个表中的所有相关数据,以获取足够的数据,以便以后可以执行数据透视。
下面列出的是我正在使用的3个表的示例。
“ FileTable”:
select thread_starter, count(*)
from ./file.csv
group by thread_starter
order by 2 desc;
“ TagTable”:
---------------------
|FileTable |
---------------------
| Id | Name |
---------------------
| 1 | File1.docx |
| 2 | File2.xlsx |
| 3 | File3.pdf |
---------------------
“ TagValueTable”:
---------------
|TagTable |
---------------
| Id | Name |
---------------
| 1 | Tag1 |
| 2 | Tag2 |
| 3 | Tag3 |
| 4 | Tag4 |
| 5 | Tag5 |
| 6 | Tag6 |
---------------
我正在尝试编写一个查询,该查询将向我显示文件,并提供所有可用标签以及包含这些文件的标签值的所有可用标签。
我编写了以下查询,但是如果“ TagValue”表中有一个值,它只会显示文件和标签。
------------------------------------
|TagValueTable |
------------------------------------
|FileId | TagId | Value |
------------------------------------
| 1 | 1 | file1tag1value |
| 1 | 2 | file1tag2value |
| 1 | 4 | file1tag4value |
| 2 | 1 | file2tag1value |
| 2 | 4 | file2tag4value |
------------------------------------
我希望结果显示如下。
SELECT
f.Id AS 'FileId', f.[Name] AS 'FileName',
t.[Name] AS 'TagName',
tv.[Value] AS 'TagValue'
FROM
[FileTable] f
JOIN
TagValueTable tv ON tv.FileId = ISNULL(f.Id, tv.FileId)
JOIN
TagTable t ON t.Id = ISNULL(tv.TagId, t.Id)
ORDER BY
f.Id
查询需要显示所有文件的所有可用标签及其标签值。如果文件没有标签值,则应为null。我确信可能有更好的设计,但是我必须处理现有数据,因此我无法进行更改。
我尝试使用不同的联接以多种不同方式重写上述查询,但似乎无法正常工作。另外,我也在视图中执行此操作,因此无法使用存储过程。
感谢您的帮助...
谢谢
罗伯特
答案 0 :(得分:3)
您可以在此处使用CROSS JOIN和OUTER JOIN代替INNER JOIN。
SELECT
f.Id as FileID,
f.Name AS FileName,
t.Name AS TagName,
tv.Value AS TagValue
FROM FileTable f
CROSS JOIN TagTable t
LEFT JOIN TagValueTable tv ON tv.FileId = f.Id
AND tv.TagId = t.Id
CROSS JOIN将为您提供FileTable和TagTable的所有排列。 LEFT JOIN将引入TagValueTable中的标记值,同时保留先前JOIN的所有结果。内部联接(例如您正在使用的联接)将仅返回两个表中匹配的记录。
这是一个有关INNER和OUTER连接之间区别的问题。
What is the difference between "INNER JOIN" and "OUTER JOIN"?
答案 1 :(得分:0)
select x.FileId, x.FileName, x.TagName, tv.Value
from (
select f.id FileId, f.name FileName, t.id TagId, t.Name TagName
from FileTable f, TagTable t
) x
left join TagValueTable tv on x.FileId = tv.FileId and x.TagId = tv.TagId
答案 2 :(得分:0)
由于您需要每个文件的每个标签,因此需要先CROSS APPLY
个标签,然后LEFT OUTER JOIN
个链接表才能获得与该文件关联的Value
和标签。
设置
CREATE TABLE FileTable ( Id int, Name varchar(20) ) ; INSERT INTO FileTable (Id, Name) VALUES ( 1, 'File1.docx' ), ( 2, 'File2.xlsx' ), ( 3, 'File3.pdf' ) ; CREATE TABLE TagTable ( Id int, Name varchar(20) ) ; INSERT INTO TagTable (Id, Name) VALUES ( 1, 'Tag1' ) , ( 2, 'Tag2' ) , ( 3, 'Tag3' ) , ( 4, 'Tag4' ) , ( 5, 'Tag5' ) , ( 6, 'Tag6' ) ; CREATE TABLE TagValueTable ( FileId int, TagId int, theValue varchar(20) ); INSERT INTO TagValueTable (FileId, TagId, theValue) VALUES (1,1,'file1tag1value') , (1,2,'file1tag2value') , (1,4,'file1tag4value') , (2,1,'file2tag1value') , (2,4,'file2tag4value') ;
查询:
SELECT ft.Name, ca.TagName, tvt.theValue FROM FileTable ft CROSS APPLY ( SELECT tt.ID AS TagID, tt.Name AS TagName FROM TagTable tt ) ca LEFT OUTER JOIN TagValueTable tvt ON ft.ID = tvt.FileID AND ca.TagID = tvt.TagID GO
Name | TagName | theValue :--------- | :------ | :------------- File1.docx | Tag1 | file1tag1value File1.docx | Tag2 | file1tag2value File1.docx | Tag3 | null File1.docx | Tag4 | file1tag4value File1.docx | Tag5 | null File1.docx | Tag6 | null File2.xlsx | Tag1 | file2tag1value File2.xlsx | Tag2 | null File2.xlsx | Tag3 | null File2.xlsx | Tag4 | file2tag4value File2.xlsx | Tag5 | null File2.xlsx | Tag6 | null File3.pdf | Tag1 | null File3.pdf | Tag2 | null File3.pdf | Tag3 | null File3.pdf | Tag4 | null File3.pdf | Tag5 | null File3.pdf | Tag6 | null
db <>提琴here