我有 5 张 table :
- 文件
- 标签
- join_File_Tags
- 个人资料
- join_Profile_Tags
配置文件和 join_Profile_Tags 表确定用户可以查看哪些文件。
数据可能如下所示:
- File1 具有标签一、三
- 文件2具有标签一、五
- File3 具有标签一、三、六
- 个人资料 1 有权访问标签二、三、四
- 个人资料 2 有权访问标签一、二、三、四 ,五
我需要一个查询来返回与配置文件标签列表中的所有标签相匹配的文件。
我想出了这个:
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> 因为该标签具有 six 标签,而 profile2 无权访问该标签。我需要一个构建标签云的查询(基于 j_profile_tags 表没什么大不了的),但我需要标签包含文件计数。我需要标记 One 显示数字 2,Three 显示 1,Five 显示 1。到目前为止,我尝试的查询包括所有的计数因此,即使 Profile2 无权访问第三个文件,标签 One 的计数仍为 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
最佳答案
我不完全了解您的表格,尤其是“员工”列。 但如果您的意思是获取由配置文件过滤的每个标签中包含的文件数量,那么请尝试以下查询:
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
这些可能不是您问题的真正答案,但可能对您有所帮助。
关于mysql - 如何编写查询来计算具有多个约束和匹配的记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36463416/