0
votes

Joindre deux tables sur plusieurs valeurs de la colonne de jointure

Je suis coincé dans une situation où je suis incapable de progresser. L'exigence est ci-dessous.

J'ai deux tables dont l'une est ContentTag

ContentId     FolderId
   48            2

Cela contient le lien entre la table de contenu et la table de balises

et il y a une table foldettag qui contient la liaison entre la table des dossiers et la table des balises

Id      FolderId    TagId   
2           2         3     
3           2         4     
4           2         5     
5           2         6     
6           4         3     
7           5         1     
8           5         2     
9           5         3     
10          10        1         

le dossier ne contiendra que les contenus liés à toutes les balises aimant le dossier.

Remarque: j'ai besoin du résultat qui contient le lien de ces contentId et FolderId qui sont liés exactement aux mêmes balises.

par exemple, il contiendra le résultat suivant

   Id   ContentId   TagId
   1        48       3
   2        48       4
   3        48       5
   4        48       6
   5        47       7
   6        47       8
   9        47       1
   10       47       2

Quelqu'un peut-il me suggérer une approche que je devrais suivre pour procéder?

J'essaye de trouver une solution depuis quelques heures mais je ne trouve aucune solution Merci


5 commentaires

Comment savez-vous quelles balises sont appréciées? Quels résultats voulez-vous. La vraie question n'est pas claire.


HI @GordonLinoff, les balises sont liées au contenu et les dossiers sont également liés aux balises, donc j'ai besoin de lier le contenu au dossier et de le filtrer pour n'avoir que les contenus qui sont liés à toutes les balises


Quelle est votre version de SQL Server?


@forpas serveur sql 2016


@forpas Désolé son serveur SQL 2017, avez-vous quelque chose qui est pris en charge dans la nouvelle version


3 Réponses :


0
votes

Si vous voulez un résultat avec le dossier et tout le contenu qui a au moins une balise correspondante, alors join devrait suffire:

select ft.folderid, ct.contentid
from foldertags ft join
     contenttag ct
     on ft.tagid = ct.tagid


1 commentaires

mais il donnera à toutes les données sa simple jointure. J'ai besoin de filtrer ce résultat afin qu'il ne contienne que les contentid qui sont liés exactement aux mêmes balises car le dossier est lié aux balises. J'essaierai d'élaborer un peu plus mon problème



1
votes

Dans SQL Server 2017, vous pouvez utiliser STRING_AGG() :

> ContentId | FolderId
> --------: | -------:
>        48 |        2

Voir la démo .
Résultats:

WITH 
  c AS (
    SELECT ContentId, STRING_AGG(TagId, ',') WITHIN GROUP (ORDER BY TagId) tags
    FROM ContentTag
    GROUP BY ContentId
  ),
  f AS (
    SELECT FolderId, STRING_AGG(TagId, ',') WITHIN GROUP (ORDER BY TagId) tags
    FROM FolderTag
    GROUP BY FolderId
  )  
SELECT c.ContentId, f.FolderId
FROM c INNER JOIN f
ON f.tags = c.tags


0 commentaires

1
votes
declare @ContentTag table
(
Id int identity,
ContentId int,
TagId int
);
insert into @ContentTag(ContentId, TagId)
values
(48, 3), (48, 4), (48, 5), (48, 6),
(47, 7), (47, 8), (47, 1), (47, 2), 
(46, 4), (46, 6);

declare @FolderTag table
(
Id int identity,
FolderId int,
TagId int
);

insert into @FolderTag(FolderId, TagId)
values
(2, 3), (2, 4), (2, 5), (2, 6),
(4, 3), (5, 1), (5, 2), (5, 3), (10, 1),
(11, 4), (11, 6);

select f.FolderId, c.ContentId
from 
(
    select FolderId, TagId, count(*) over(partition by FolderId) as FolderTagCount
    from @FolderTag
) as f
join
(
    select ContentId , TagId, count(*) over(partition by ContentId) as ContentTagCount
    from @ContentTag
) as c on f.TagId = c.TagId and f.FolderTagCount = c.ContentTagCount
group by f.FolderId, c.ContentId
having count(f.TagId) = max(c.ContentTagCount);

0 commentaires