Php mySQL连接三个表并搜索在一个表中找到的几个关键字

Php mySQL连接三个表并搜索在一个表中找到的几个关键字,php,mysql,Php,Mysql,我试图通过避免包含相同单词的多个记录来限制数据库的大小,因此我构建了两个表,用于将关键字与其他表中的行关联起来 例如,我们使用以下搜索输入:“查找我的” 希望获得成功的是product_id=106中的product_名称。 我可以搜索一下产品名称吗?否,因为产品可以与其他关键字关联,这些关键字不属于产品名称的一部分 表:欧共体产品 product_id | product_name | is_deleted -------------------------------------

我试图通过避免包含相同单词的多个记录来限制数据库的大小,因此我构建了两个表,用于将关键字与其他表中的行关联起来

例如,我们使用以下搜索输入:“查找我的”

希望获得成功的是product_id=106中的product_名称。 我可以搜索一下产品名称吗?否,因为产品可以与其他关键字关联,这些关键字不属于产品名称的一部分

表:欧共体产品

product_id    | product_name    | is_deleted
---------------------------------------------
106           | some product    | 0
表:ec_关键字索引

word_id       | keyword
---------------------------------------------
55            | find
61            | my
77            | product
表:ec_关键字_关系

word_id       | application_id    | related_id
------------------------------------------------
55            | 1                 | 106
61            | 1                 | 106
77            | 1                 | 106
因此,当我在搜索输入中输入“查找我的”时,我现在想要的是:

  • 我只想点击ec_关键字_relations.application_id=1的位置
  • 我的搜索字符串中的所有单词都应该与产品相关。例如,如果我将搜索输入更改为“查找我的裤子”,则我们不应查找product_id=106
以下是我迄今为止所做的尝试(我知道我目前离一个有效的解决方案还很远):

更新:

经过一番折腾,我终于想出了这个解决方案,它的效果和预期的一样。它(就性能而言)是一个好的解决方案还是一个坏的解决方案

    $searchInput = 'find my';
    $keywords = explode(' ', $searchInput);

    $keyword_count = count($keywords);

    $n = 1;
    $where_query = '';
    $having_query = '';

    foreach($keywords as $keyword) { 
        if ($n != $keyword_count) {
            $w_query_ext = ' OR '; 
            $h_query_ext = ' AND ';
        } else { 
            $w_query_ext = ''; 
            $h_query_ext = ''; 
        }

        $where_query .= "ec_keywords_index.keyword LIKE '%" . $keyword . "%'" . $w_query_ext;

        $having_query .= "related_keywords LIKE '%" . $keyword . "%'" . $h_query_ext;

        ++$n;
    }

    $query = "
        SELECT 
            ec_products.product_name, 
            GROUP_CONCAT(' ', ec_keywords_index.keyword) AS 'related_keywords'

        FROM 
            ec_products, 
            ec_keywords_index

        LEFT JOIN 
            ec_keyword_relations 
            ON ec_keyword_relations.word_id = ec_keywords_index.word_id

        WHERE ($where_query) 
            AND ec_products.product_id = ec_keyword_relations.related_id 
            AND ec_keyword_relations.application_id = '1' 
            AND ec_products.is_deleted = '0'

        GROUP BY 
            ec_products.product_name

        HAVING 
            ($having_query)

        LIMIT 
            100";

    $stmt = $mysqli->prepare($query);
    $stmt->execute();
    $stmt->store_result();
    $stmt->bind_result($name);
    while ($stmt->fetch()) {
        echo $name;
    }
    $searchInput = 'find my';
    $keywords = explode(' ', $searchInput);

    $keyword_count = count($keywords);

    $n = 1;
    $where_query = '';
    $having_query = '';

    foreach($keywords as $keyword) { 
        if ($n != $keyword_count) {
            $w_query_ext = ' OR '; 
            $h_query_ext = ' AND ';
        } else { 
            $w_query_ext = ''; 
            $h_query_ext = ''; 
        }

        $where_query .= "ec_keywords_index.keyword LIKE '%" . $keyword . "%'" . $w_query_ext;

        $having_query .= "related_keywords LIKE '%" . $keyword . "%'" . $h_query_ext;

        ++$n;
    }

    $query = "
        SELECT 
            ec_products.product_name, 
            GROUP_CONCAT(' ', ec_keywords_index.keyword) AS 'related_keywords'

        FROM 
            ec_products, 
            ec_keywords_index

        LEFT JOIN 
            ec_keyword_relations 
            ON ec_keyword_relations.word_id = ec_keywords_index.word_id

        WHERE ($where_query) 
            AND ec_products.product_id = ec_keyword_relations.related_id 
            AND ec_keyword_relations.application_id = '1' 
            AND ec_products.is_deleted = '0'

        GROUP BY 
            ec_products.product_name

        HAVING 
            ($having_query)

        LIMIT 
            100";

    $stmt = $mysqli->prepare($query);
    $stmt->execute();
    $stmt->store_result();
    $stmt->bind_result($name);
    while ($stmt->fetch()) {
        echo $name;
    }
上面的示例输出如下查询:

    SELECT 
        ec_products.product_name, 
        GROUP_CONCAT(' ', ec_keywords_index.keyword) AS 'related_keywords'

    FROM 
        ec_products, 
        ec_keywords_index

    LEFT JOIN 
        ec_keyword_relations 
        ON ec_keyword_relations.word_id = ec_keywords_index.word_id

    WHERE (ec_keywords_index.keyword LIKE '%find%' OR ec_keywords_index.keyword LIKE '%my%') 
        AND ec_products.product_id = ec_keyword_relations.related_id 
        AND ec_keyword_relations.application_id = '1' 
        AND ec_products.is_deleted = '0'

    GROUP BY 
        ec_products.product_name

    HAVING 
        (related_keywords LIKE '%find%' AND related_keywords LIKE '%my%')

    LIMIT 
        100
    SELECT 
        ec_products.product_name, 
        GROUP_CONCAT(' ', ec_keywords_index.keyword) AS 'related_keywords'

    FROM 
        ec_products, 
        ec_keywords_index

    LEFT JOIN 
        ec_keyword_relations 
        ON ec_keyword_relations.word_id = ec_keywords_index.word_id

    WHERE (ec_keywords_index.keyword LIKE '%find%' OR ec_keywords_index.keyword LIKE '%my%') 
        AND ec_products.product_id = ec_keyword_relations.related_id 
        AND ec_keyword_relations.application_id = '1' 
        AND ec_products.is_deleted = '0'

    GROUP BY 
        ec_products.product_name

    HAVING 
        (related_keywords LIKE '%find%' AND related_keywords LIKE '%my%')

    LIMIT 
        100

我正在使用GROUP_CONCAT创建一个列,其中包含与产品相关的所有关键字,然后使用我的WHERE子句仅选择在搜索字符串中实际找到的关键字。。。然后HAVING子句用于使用GROUP_CONCAT在列构建中搜索。

自己的答案,并举例说明:

经过一番折腾,我终于想出了这个解决方案,它的效果和预期的一样。我不知道这是否是最好的做法,但它就像一个魅力

上面的示例输出如下查询:

    SELECT 
        ec_products.product_name, 
        GROUP_CONCAT(' ', ec_keywords_index.keyword) AS 'related_keywords'

    FROM 
        ec_products, 
        ec_keywords_index

    LEFT JOIN 
        ec_keyword_relations 
        ON ec_keyword_relations.word_id = ec_keywords_index.word_id

    WHERE (ec_keywords_index.keyword LIKE '%find%' OR ec_keywords_index.keyword LIKE '%my%') 
        AND ec_products.product_id = ec_keyword_relations.related_id 
        AND ec_keyword_relations.application_id = '1' 
        AND ec_products.is_deleted = '0'

    GROUP BY 
        ec_products.product_name

    HAVING 
        (related_keywords LIKE '%find%' AND related_keywords LIKE '%my%')

    LIMIT 
        100
    SELECT 
        ec_products.product_name, 
        GROUP_CONCAT(' ', ec_keywords_index.keyword) AS 'related_keywords'

    FROM 
        ec_products, 
        ec_keywords_index

    LEFT JOIN 
        ec_keyword_relations 
        ON ec_keyword_relations.word_id = ec_keywords_index.word_id

    WHERE (ec_keywords_index.keyword LIKE '%find%' OR ec_keywords_index.keyword LIKE '%my%') 
        AND ec_products.product_id = ec_keyword_relations.related_id 
        AND ec_keyword_relations.application_id = '1' 
        AND ec_products.is_deleted = '0'

    GROUP BY 
        ec_products.product_name

    HAVING 
        (related_keywords LIKE '%find%' AND related_keywords LIKE '%my%')

    LIMIT 
        100
我正在使用GROUP_CONCAT创建一个列,其中包含与产品相关的所有关键字,然后使用我的WHERE子句仅选择在搜索字符串中实际找到的关键字。。。然后HAVING子句用于使用GROUP_CONCAT在列build中搜索