2016-04-06 5 views
0

Ich habe 5 Tabellen:Wie schreibe ich eine Abfrage, um Datensätze mit mehreren Einschränkungen und Übereinstimmungen zu zählen?

  1. Dateien
  2. Stichworte
  3. join_File_Tags
  4. Profile
  5. join_Profile_Tags

Die Profile und die join_Profile_Tags Tabellen bestimmen, die sehen kann ein Benutzer Dateien.

Daten könnte wie folgt aussehen:

  • File1 hat Tags One, Drei
  • File2 hat Tags One, Fünf
  • File3 hat Markierungen One, Drei, Sechs
  • Profile1 Zugriff auf Variablen Zwei, Drei, Vier
  • Profile2 hat Zugriff auf Tags One, Zwei hat, Drei, Vier, Fünf

brauchte ich eine Abfrage, die die Dateien zurückgibt, dass alle ihre Tags in einem Profil-Liste der Tags entsprechen.

Und ich kam mit dieser:

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*/ 

Das gibt mir genau das, was ich brauche. ABER was ich versuche, jetzt zu bekommen ist: Wie viele Dateien gibt es in jedem Tag?

So in meinem Beispiel Daten an der Spitze, der Profile2 Benutzer File1 und File2 aber nicht File3 sehen, weil das ein Tag hat sechs, die profile2 keinen Zugang zu. Ich brauche eine Abfrage, die eine Tag Cloud erstellt (kein Biggie basierend auf der Tabelle j_profile_tags), aber ich brauche die Tags, um die Anzahl der Dateien einzuschließen. Ich brauche Tag One, um die Nummer 2, Drei zeigt 1, Five zeigt 1 zu zeigen.Die Abfragen, die ich bisher versucht habe, enthalten die Anzahl aller Dateien. Daher wird Tag One mit einer Anzahl von 3 angezeigt, obwohl Profile2 keinen Zugriff auf diese dritte Datei hat. Hier ist meine halbe Arbeits query:

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

Wenn LEFT JOIN, setzen Sie die Bedingungen der rechten Seitentabelle in die ON-Klausel, um echtes linkes Join-Verhalten zu erhalten. (Wenn in WHERE, erhalten Sie innere Join-Ergebnis ...) – jarlh

+0

Ich aktualisiert die INNER JOIN in meiner letzten Abfrage, wie Sie vorgeschlagen. –

+0

I Kommentar war eher in Bezug auf Ihre erste Abfrage, die mit LEFT JOIN's. – jarlh

Antwort

0

ich voll und ganz über Ihre Tabellen nicht verstehen, vor allem, dass „Mitarbeiter“ Spalte. Aber wenn das, was du meinst ist immer Wie viele Dateien, die von einem Profil gefiltert in jedem Tag enthalten ist, dann versuchen Sie bitte die folgende Anfrage:

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 

Dies ist vielleicht nicht die richtige Antwort auf Ihre Frage sein, aber könnte eine Hilfe sein, um dich dorthin zu bringen.

+0

Ihre letzte Abfrage gibt die Anzahl der Tags zurück, auf die das Profil zugreifen kann, zusammen mit der Anzahl der Dateien, die dieses Tag haben. ABER: (1) Es gibt auch alle anderen Tags mit einer Zählung von 0 für Dateien zurück, die nicht benötigt werden am wichtigsten (2) ist die Zählung für alle Dateien in der Dateitabelle, wie würde ich dort eine weitere Bedingung hinzufügen? so wie "where files.caseID = 1 –

Verwandte Themen