代码之家  ›  专栏  ›  技术社区  ›  Jens Törnell

在mysql中使用where match对concat进行分组

  •  1
  • Jens Törnell  · 技术社区  · 6 年前

    我正在用SQL开发一个简单的搜索函数,结果被卡住了。我使用GROUP_CONCAT将所有关键字放在一行中。关键词取自类别。

    并非所有列都在本例中。我把它剥去了

    SELECT
      p.id as id,
      p.title as title,
      p.title as company,
      GROUP_CONCAT(DISTINCT cat.title SEPARATOR " ") as keywords,
      FROM products p
        JOIN product_categories pc ON p.id = pc.product_id
        JOIN categories cat ON pc.category_id = cat.id
        JOIN companies co ON p.company_id = co.id
     WHERE MATCH (p.title) AGAINST ("Test")
     OR MATCH (co.title) AGAINST ("Test")
     GROUP BY p.id
    

    keywords 包含以下内容 keyword1 keyword2 keyword3 .

    上面的SQL正在运行。但是,我不能将MATCH与虚拟值一起使用 关键词 价值

    我读过一些关于我认为是一个丑陋的解决方法的文章,补充如下:

    HAVING keywords LIKE "%keyword1%"
    

    LIKE可能很慢,因为HAVING is after GROUP BY我不能使用,所以在这种情况下HAVING将覆盖WHERE。

    理想情况下,我想用一场比赛来对抗 关键词 也那么,我的选择是什么?

    • 某种虚拟桌子?
    • 子查询?
    • 还有别的吗?

    1 回复  |  直到 6 年前
        1
  •  1
  •   spencer7593    6 年前

    这并没有回答您提出的问题,但我认为将此条件添加到查询的WHERE子句中:

        OR EXISTS ( SELECT 1
                      FROM categories k 
                     WHERE k.id = pc.category_id
                       AND k.title IN ('Test1','Test2')
                  )    
    

    GROUP BY 无需扫描 GROUP_CONCAT ,如果规范要返回类别标题与指定搜索词之一匹配的行。


    如果不需要实际返回派生的 keywords 列中,我会避免使用分组方式。

    SELECT p.id AS id
         , p.title AS title
         , p.title AS company
      FROM products p
      JOIN companies co
        ON co.id = p.company_id
     WHERE MATCH (p.title) AGAINST ('Test')
        OR MATCH (co.title) AGAINST ('Test')
        OR EXISTS ( SELECT 1
                      FROM categories k
                      JOIN product_categories pc
                        ON pc.category_id = k.id
                     WHERE pc.product_id = p.id
                       AND k.title IN ('Test1','Test2')
                  )
     ORDER BY p.id