【问题标题】:Querying a Many-to-Many Linking Table查询多对多链接表
【发布时间】:2019-11-10 11:18:48
【问题描述】:

我有一个多对多关系的链接表,其中包含字段 -

  • idNote
  • idTag

我想过滤所有与包含指定数量标签的笔记相关联的标签。

例如,如果我选择标签“Running”、“Form”和“Times”,那么我想查看与具有这 3 个标签的注释相关联的所有标签.

前端的用户将使用此过程来细化他们正在寻找的结果,因此我需要能够使用代码 (node.js) 生成此 SQL,并通过标签进行过滤可能会发生很多多次。

我有下面的SQL代码,可以查询两个标签,但是有一些问题:

  1. 好像效率不高
  2. 如果需要再增加一层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');

希望对如何提高这段代码的效率,以及将sql语句变成易于代码生成的东西提出一些建议。

【问题讨论】:

    标签: mysql sql node.js querying


    【解决方案1】:

    听起来像是数据陷阱,笛卡尔积 https://en.wikipedia.org/wiki/Cartesian_product

    有什么可以连接这两个表吗? 就像我们可以加入的两者之间的公用表一样? 而不是 N:N
    表 A 与注释表 (B) 和标签表 (C) 相同 我们可以让表 A 以 1:N 的形式加入表 B 并且表 A 也以 1:N 的形式加入到 C 中

    然后您可以将两个单独的事实与一个公用表拼接在一起

    【讨论】:

    • 其实是一张包含多对多关系的单表;我有一个标签表,我有一个笔记表。它们链接在第三张表中,其中包含标签和注释之间的所有链接。我正在尝试过滤第三张桌子
    【解决方案2】:

    试试这样的:

    ; 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]
    

    您在其中生成包含所有搜索标签的 CTE(通用表表达式)。加入多对多关系表,只选择那些计数等于用户输入的搜索标签数的笔记,在查询中注明[NUMBER_OF_SEARCH_TAGS]

    【讨论】:

    • 据我所知,mysql支持CTE和have子句
    • 感谢您的回答!我还没有遇到 CTE,所以我将不得不进一步研究它们,看看我是否可以应用它
    【解决方案3】:

    我使用您的'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'))
    
    
    

    【讨论】:

    • 您好,谢谢您的回答!不幸的是,问题是这个过滤器过滤了任何具有 3 个标签的 idnote,而我需要过滤具有所有 3 个标签的 idnote
    • 好的 - 我不明白。我将答案更改为适用于所有 3 的内容。现在我明白了,不确定这是否符合您对代码生成的“简单性”要求(取决于某人一次可以选择多少个标签),但我相信这会工作。
    • 谢谢,这实际上似乎工作得很好!它很容易生成代码,因为我所要做的就是在每次应用进一步的过滤器时附加一个新的 'and' 子句。
    猜你喜欢
    • 1970-01-01
    • 2020-03-26
    • 1970-01-01
    • 1970-01-01
    • 2010-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-23
    相关资源
    最近更新 更多