繁体   English   中英

如何编写查询以对具有多个约束和匹配项的记录进行计数?

[英]How do I write a query to count records with multiple constraints and matches?

我有5张桌子:

  1. 档案
  2. 标签
  3. join_File_Tags
  4. 个人资料
  5. join_Profile_Tags

配置文件和join_Profile_Tags表确定用户可以看到哪些文件。

数据可能如下所示:

  • 文件1有标签
  • 文件2有标签
  • 文件3具有标签
  • Profile1的访问标记
  • PROFILE2访问标签

我需要一个查询,该查询返回与“个人档案”的标签列表内的所有标签匹配的文件。

我想到了这个:

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用户将看到File1File2,但看不到File3,因为该用户具有标签6 ,而profile2无法访问。 我需要一个构建标签云的查询(基于j_profile_tags表不算大),但是我需要标签来包含文件计数。 我需要标记One来显示数字2, 三个显示1, 五个显示1。到目前为止,我尝试的查询包括所有文件的计数,所以即使Profile2没有访问权限,标记1的计数也为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

我不完全了解您的表,尤其是“雇员”列。 但是,如果您要获取的是通过Profile过滤的每个标记中包含多少文件,请尝试以下查询:

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

这些可能不是您问题的真正答案,但可能有助于您到达那里。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM