简体   繁体   English

查询多对多链接表

[英]Querying a Many-to-Many Linking Table

I have a linking table for a many-to-many relationship, with the fields -我有一个多对多关系的链接表,其中包含字段 -

  • idNote身份证
  • idTag身份标签

I would like to filter for all the tags that are associated with the notes that contain a specified number of tags.我想过滤与包含指定数量标签的笔记相关联的所有标签。

For example, if I select the tags ' Running ', ' Form ', and ' Times ', I would then like to see all the tags that are associated with the notes that have these 3 tags.例如,如果我选择标签“ Running ”、“ Form ”和“ Times ”,那么我想查看与具有这 3 个标签的笔记相关联的所有标签。

This process will be used by the user on the front end to refine the results they are looking for, so I need to be able to generate this SQL with code ( node.js ), with the filtering by tags potentially occurring many times over.前端的用户将使用此过程来优化他们正在查找的结果,因此我需要能够使用代码 ( node.js ) 生成此 SQL,并且可能会多次进行标签过滤。

I have the below SQL code, which can query for two tags, but there are some problems with it:我有下面的SQL代码,可以查询两个标签,但是有一些问题:

  1. It does not seem efficient似乎效率不高
  2. It can not be easily generated through code if another layer of filers needs to be added如果需要添加另一层filer,则无法通过代码轻松生成
SELECT DISTINCT idtag FROM table WHERE idnote IN (SELECT idnote FROM 
(SELECT * FROM table WHERE idnote IN (SELECT idnote FROM table WHERE idtag 
= 'Example')) as t1 where t1.idtag = 'SecondExample');

I am hoping for some suggestions on how to improve the efficiency of this code, as well as turning the sql statement into something that is easily code generateable.我希望就如何提高此代码的效率以及将 sql 语句转换为易于代码生成的内容提出一些建议。

Sounds like a data trap, the Cartesian product https://en.wikipedia.org/wiki/Cartesian_product听起来像一个数据陷阱,笛卡尔积https://en.wikipedia.org/wiki/Cartesian_product

Is there anything to bridge the two tables?有什么东西可以桥接这两个表吗? Like a common table between the two that we can join to?就像我们可以加入的两者之间的公共表? Instead of N:N代替 N:N
Table A would be something in common with the notes table (B) and tags table (C) we could have Table A join to Table B as 1:N and Table A also join to C as 1:N表 A 与笔记表 (B) 和标签表 (C) 有一些共同点,我们可以让表 A 以 1:N 的形式连接到表 B,而表 A 也以 1:N 的形式连接到 C

Then you could stitch the two separate facts together with a common table然后你可以用一个共同的表格将两个单独的事实拼接在一起

Try something like this:尝试这样的事情:

; with cteTagList as 
    (select 'Example' idtag
    union select 'SecondExample'
    --...
    union select 'LastExample'
    )
select t.idnote
from table t inner join cteTabList l on l.idtag = t.idtag
group by t.idnote
having count(*) = [NUMBER_OF_SEARCH_TAGS]

Where you generate a CTE (Common Table Expression) which contains all the search tags.在其中生成包含所有搜索标签的 CTE(公用表表达式)。 Join it with the many-to-many relation table, and only select those notes that hat count equal to the number of search tags inputed by the user, noted [NUMBER_OF_SEARCH_TAGS] in the query将它与多对多关系表连接起来,只选择那些帽子数等于用户输入的搜索标签数量的笔记,在查询中注明[NUMBER_OF_SEARCH_TAGS]

I used your example of 'Running','Form','Times' as the specified set of tags.我使用您的'Running','Form','Times'示例作为指定的标签集。

select distinct idTag from table 
where idNote in (select idNote from table where idTag in ('Running'))
and idNote in (select idNote from table where idTag in ('Form'))
and idNote in (select idNote from table where idTag in ('Times'))


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

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