我有5张桌子:
“个人档案”和“join_Profile_Tags”表确定用户可以看到的文件。
数据可能如下所示:
我需要一个查询,返回与Profile的标签列表中的所有标签匹配的文件。
我想出了这个:
SELECT
files.id,
files.FileName,
(SELECT COUNT(j_file_tags.id) from j_file_tags WHERE j_file_tags.fileID = files.id ) as fileTagCount
FROM files
LEFT JOIN j_file_tags ON j_file_tags.fileID = files.id
LEFT JOIN tags ON tags.id = j_file_tags.tagID
WHERE
files.caseID = '123456'
AND
j_file_tags.tagID IN ("One, Two, Three, Four, Five") /* i can get these before hand */
GROUP BY
files.id
HAVING
COUNT(j_file_tags.id) = fileTagCount /* this makes sure that the user has access to ALL the tags applied to the file*/
这正是我所需要的。但我现在想要的是:每个标签中有多少个文件?
因此,在顶部的示例数据中, Profile2 用户将看到 File1 和 File2 ,但 File3 >因为那个标签六,哪个profile2无权访问。我需要一个构建标签云的查询(没有基于j_profile_tags表的biggie),但我需要标签包含文件计数。我需要标记一个来显示数字2,三个显示1,五个显示1.我到目前为止尝试的查询包括所有的计数文件,因此即使 Profile2 无法访问该第三个文件,标记一个也会计入3。 这是我的半工作查询:
SELECT
tags.id,
tags.TagName,
COUNT(tags.id) as tagCount
FROM
tags
INNER JOIN j_file_tags ON tags.id = j_file_tags.tagID
INNER JOIN files ON j_file_tags.fileID = files.id
INNER JOIN j_profile_tags ON j_profile_tags.tagID = tags.id AND j_profile_tags.profileID = 'Profile2'
WHERE
files.caseID = '123456'
GROUP BY
tags.id
答案 0 :(得分:0)
我不完全了解您的表格,尤其是 “员工” 列。 但是,如果您的意思是 每个标记中包含的文件 过滤了多少个文件,那么请尝试以下查询:
DECLARE @TblFiles AS TABLE(ID int identity(1, 1) primary key, TheFileName varchar(50))
DECLARE @TblTags AS TABLE(ID int identity(1, 1) primary key, TheTag varchar(50))
DECLARE @TblProfiles AS TABLE(ID int identity(1, 1) primary key, TheProfile varchar(50))
DECLARE @TblFileTagMapper AS TABLE(ID int identity(1, 1) primary key, FileID int, TagID int)
DECLARE @TblProfileTagMapper AS TABLE(ID int identity(1, 1) primary key, ProfileID int, TagID int)
INSERT INTO @TblFiles(TheFileName) VALUES ('File1'), ('File2'), ('File3')
INSERT INTO @TblTags(TheTag) VALUES ('One'), ('Two'), ('Three'), ('Four'), ('Five'), ('Six')
INSERT INTO @TblProfiles(TheProfile) VALUES ('Profile1'), ('Profile2')
INSERT INTO @TblFileTagMapper(FileID, TagID) VALUES (1,1), (1,3), (2,1), (2,5), (3,1), (3,3), (3,6)
INSERT INTO @TblProfileTagMapper(ProfileID, TagID) VALUES (1,2), (1,3), (1,4), (2,1), (2,2), (2,3), (2,4), (2,5)
--Display File-Tag
SELECT TheFileName
,STUFF((SELECT ', ' + CAST(TheTag AS VARCHAR(10)) [text()]
FROM (SELECT F.TheFileName, T.TheTag FROM @TblFileTagMapper FT INNER JOIN @TblFiles F ON FT.FileID = F.ID INNER JOIN @TblTags T ON FT.TagID = T.ID) FT
WHERE TheFileName = t.TheFileName
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') Tags
FROM (SELECT F.TheFileName, T.TheTag FROM @TblFileTagMapper FT INNER JOIN @TblFiles F ON FT.FileID = F.ID INNER JOIN @TblTags T ON FT.TagID = T.ID) t
GROUP BY TheFileName
--Display Profile-Tag
SELECT TheProfile
,STUFF((SELECT ', ' + CAST(TheTag AS VARCHAR(10)) [text()]
FROM (SELECT P.TheProfile, T.TheTag FROM @TblProfileTagMapper PT INNER JOIN @TblProfiles P ON PT.ProfileID = P.ID INNER JOIN @TblTags T ON PT.TagID = T.ID) PT
WHERE TheProfile = t.TheProfile
FOR XML PATH(''), TYPE)
.value('.','NVARCHAR(MAX)'),1,2,' ') Tags
FROM (SELECT P.TheProfile, T.TheTag FROM @TblProfileTagMapper PT INNER JOIN @TblProfiles P ON PT.ProfileID = P.ID INNER JOIN @TblTags T ON PT.TagID = T.ID) t
GROUP BY TheProfile
--> Param Input
DECLARE @ParamProfile VARCHAR(50) = 'Profile2'
--> The Solution Query
SELECT T.TheTag, COALESCE(X.FileCount, 0) AS NumberOfFilesWhichContainTheTag
FROM @TblTags T
LEFT JOIN(
SELECT FT.TagID, COUNT(FT.FileID) AS FileCount
FROM @TblFileTagMapper FT
WHERE EXISTS(SELECT 1 FROM @TblProfileTagMapper PT INNER JOIN @TblProfiles P ON PT.ProfileID = P.ID WHERE PT.TagID = FT.TagID AND P.TheProfile = @ParamProfile)
GROUP BY FT.TagID
) X ON T.ID = X.TagID
这些可能不是您问题的真正答案,但可能会帮助您实现目标。