0

I am creating a program in PHP where users submit a file and then can search for the file based off of 6 categories that they entered when they initially created the file. The categories are stored in a table in one cell that looks like this: category_1 category_2 category_3 etc - they are not in separate columns

I need to create a page where the user can fill in the categories that they want to search by and then submit the query to the MYSQL database. I want the page to sort the rows by which files match the most categories first.

My question is how to I set up the MYSQL query to search for 6 categories and then order the results by the rows that have the most categories matched (show the one with 3 matched categories in front of the one with 2 categories matched?

I would put up code that I tried, but I don't even know where to start (do I use regular expressions?). Any help would be great. I am familiar with PHP and HTML, but MYSQL is new to me.

4

3 に答える 3

0

カテゴリが @Categories という列にあるとします。便宜上、スペースで区切られているのではなく、コンマで区切られていると仮定します (次のコードで置換を使用できます)。これにより、説明が簡単になります。

select
from files f
order by (find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 1))), ',' 1), f.categories) > 0) +
      (find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 2)), ',' 1)), f.categories) > 0) +
      (find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 3)), ',' 1)), f.categories) > 0) +
      (find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ', ', 4), ',' 1)), f.categories) > 0) +
      (find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 5)), ',' 1)), f.categories) > 0) +
      (find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', 6)), ',' 1)), f.categories) > 0) desc

(注: これはテストされていません。)

その鍵となるのは、次の式です。

      (find_in_list(reverse(substring_index(reverse(substring_index(@Categories, ',', <n>)), ',' 1)), f.categories) > 0) +

これを裏返しに説明しましょう:

この式substring_index(@Categories, ',', <n>)は、n 番目のカテゴリまでのカテゴリ文字列を返します。

次にreverse、この文字列を反転するため、n 番目の文字列が最初になります。

substring_indexは、元の文字列の n 番目の要素である、この文字列の最初の要素を返します。でも、逆なので次のreverse. 最後に、find_in_set()はファイルのカテゴリでこれを探します。

句全体order byがこれらの値を加算します (ブール値は MySQL の整数のように加算されます)。したがって、一致の数を取得します。これは、元のデータをどのように並べたいかです。

とは言っても、これはデータのひどい構造です。これをより正規化された形式で保存すると、ソリューションははるかに簡単になります。

于 2013-06-10T02:16:14.793 に答える
0

これはあなたのために働くはずです:

 select 
    id, 
    name, sum(
       IF(find_in_set('$cat1', replace(' ',',','categories'), 1, 0) +
       IF(find_in_set('$cat2', replace(' ',',','categories'), 1, 0) +
       IF(find_in_set('$cat3', replace(' ',',','categories'), 1, 0) +
       IF(find_in_set('$cat4', replace(' ',',','categories'), 1, 0) +
       IF(find_in_set('$cat5', replace(' ',',','categories'), 1, 0) +
       IF(find_in_set('$cat6', replace(' ',',','categories'), 1, 0)) as match_score
 from products
    where match_score > 0 
 order by match_score desc;
于 2013-06-10T02:19:54.140 に答える
0

ブール値モードで MySQL の FULLTEXT 検索を使用して調査する必要があります。

http://dev.mysql.com/doc/refman/5.5/en/fulltext-boolean.html

特に、カテゴリが 1 つの列に連結されている場合、これは問題を解決するための優れた方法である可能性が非常に高くなります。

この方法で検索するテーブルまたはテーブルへのアクセス方法には MyISAM を使用する必要があります。

(注意してください: ブール モードを使用しない場合、全文検索は小さなテーブルでテストするのが困難です。小さなテキスト コーパスの単語の頻度を検出すると、予測できない結果が生じます。しかし、ブール モードを使用すれば問題ありません。)

于 2013-06-10T01:55:37.450 に答える