【问题标题】:Searching multiple rows in select with left join使用左连接在选择中搜索多行
【发布时间】:2011-05-16 15:07:12
【问题描述】:

我有 3 个表格、产品、products_tags 和标签。一个产品可以通过 products_tags 表连接到多个标签。

但是,如果我现在想搜索带有多个标签的产品,我会进行如下查询:

SELECT
    *
FROM
    products
LEFT JOIN
    products_tags
ON
    products_tags.product_id = products.id
LEFT JOIN
    tags
ON
    products_tags.tag_id = tags.id
WHERE
    tags.name = 'test'
AND
    tags.name = 'test2'

这不起作用:(。 如果我删除 AND tags.name = 'test2' 它可以工作。所以我只能按一个标签搜索,我解释了查询,它说不可能在哪里。

如何使用单个查询搜索多个标签?

谢谢!

【问题讨论】:

    标签: mysql select join


    【解决方案1】:

    您是否尝试过类似的方法:

    WHERE
        (tags.name = 'test'
    OR
        tags.name = 'test2')
    

    或者

    WHERE
        tags.name in( 'test', 'test2')
    

    因为即使您将一个产品连接到多个标签,每个标签记录也只有一个name的值。

    【讨论】:

      【解决方案2】:

      test 和 test2 需要加入两次:

      select products.*
      from products
      join product_tags as product_tag1 on ...
      join tags as tag1 on ...
      join product_tags as product_tag2 on ...
      join tags as tag2 on ...
      where tag1.name = 'test'
      and tag2.name = 'test2'
      

      对于 test 或 test2,您需要一个 join 和一个 in 子句以及一个 distinct:

      select distinct products.*
      from products
      join product_tags on ...
      join tags as tags on ...
      where tags.name IN('test', 'test2')
      

      【讨论】:

        【解决方案3】:

        您必须按和 COUNT(*) 进行分组,以确保找到 BOTH(或多个)。 第一个查询 (PreQuery) 将产品标签表连接到标签并查找与匹配的标签计数相同以查找...然后使用它来加入产品以获取最终列表

        SELECT STRAIGHT_JOIN
              p.*
           FROM
              ( select pt.product_id
                   from products_tags pt
                           join tags on pt.tag_id = tags.id
                   where tags.name in ('test1', 'test2' )
                   group by pt.product_id
                   having count(*) = 2
              ) PreQuery
              join products on PreQuery.Product_ID = Products.ID
        

        【讨论】:

        • 非常感谢我将使用这个!
        • @Chris:这是最慢的。它可能会导致将整个表与自身进行哈希连接。
        • @Denis,对产品标签进行双重连接,然后必须标记到 TAGs 表,总共需要 5 个连接...现在使用某人正在寻找的 5 个标签进行查询产品列表结果。通过使用“STRAIGHT_JOIN”子句,将仅在该级别进行预查询和聚合,并返回一个小的结果集,其中包含完全符合被测试标签计数的结果,然后加入产品表。
        • 确实是 5 个连接,但就我使用真实数据(在 WordPress 中)执行此操作的经验而言,它仍然比加入聚合要快。 :-(
        • 嘿伙计们,确保我在不幸的不是那么大的数据库上测试了这两种解决方案,带有 2 个标签。两个查询的平均速度完全相同。
        【解决方案4】:

        如果您要搜索同时具有“test”和“test2”标签的产品,则需要分别加入 product_tag 和 tag 表两次。

        此外,请使用内部连接,因为您只想要具有这些标签的产品。

        例子:

        SELECT products.*
        FROM products
        INNER JOIN products_tags pt1 ON pt1.product_id = products.id
        INNER JOIN products_tags pt2 ON pt2.product_id = products.id
        INNER JOIN tags t1 ON t1.id = pt1.tag_id
        INNER JOIN tags t2 ON t2.id = pt2.tag_id
        WHERE t1.name = 'test'
        AND t2.name = 'test2'
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-05-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2022-06-29
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多