4

これで、次の例のようにデータベースを設定できました。

id (int(11)) | name (varchar(20)) | food (varchar(20)) | fastfood (varchar(3)) | pricerange (int(11))

1            | McDonalds          | American           | Yes                   | 1
2            | Outback            | BBQ                | No                    | 2
3            | Mortons            | Steakhouse         | No                    | 3

これで、次のようにユーザーフォームを設定しました。

<form action="index.php" method="GET" id="sheet">

    <select name="name1" id="name1">
        <option value="%">No Preference</option>
        <option value="outback">Outback</option>
        <option value="mcdonalds">McDonalds</option>
        <option value="mortons">Mortons</option>
    </select>

    <select name="food1" id="food1">
        <option value="%">No Preference</option>
        <option value="american">American</option>
        <option value="bbq">BBQ</option>
        <option value="steakhouse">Steakhouse</option>
    </select>

    <select name="fast" id="fast">
        <option value="%">No Preference</option>
        <option value="yes">Yes</option>
        <option value="no">No</option>
    </select>

    <select name="price" id="price">
        <option value="%">No Preference</option>
        <option value="1">Cheap</option>
        <option value="2">Middle Ground</option>
        <option value="3">Expensive</option>
    </select>

    <input type="submit" value="Submit" id="submit"></input>
    <input type="clear" value="Clear" id="Clear"<input>

</form>

すべてのフィールドが一致しない場合に次のクエリを実行すると、結果が得られません。intクエリを操作して、 s&varcharsが関与している場合に、最適な一致に基づいて結果を表示するにはどうすればよいですか?

$query = "SELECT * FROM .$usertable 
             WHERE $name LIKE '$name' AND 
                   $food LIKE '$food1' AND 
                   $fastfood LIKE '$fast' AND 
                   $pricerange LIKE '$price' ";

INTのために全文検索は機能せず、「OR」は最適一致に基づく結果を表示しません。ユーザーが次のような4つのオプションのうち3つを選択したとします。BBQ | Yes | 2

さて、その場合の最良の一致はですがOutback、ファーストフードも一致させようとしているため、結果は返されません。そして、さらに多くのオプションがある場合、それはさらに複雑になります。

誰かがこの問題の解決策に光を当てることができれば、私は非常に感謝しています。

4

4 に答える 4

3

まず、これらの int を解析する必要があります。これらの機能は次の場合に役立ちます。

http://php.net/manual/en/function.intval.php

http://es.php.net/manual/en/function.trim.php

第二に、intが次のようになるようにクエリを操作できます$pricerange <= $price order by $pricerange desc

(このクエリは、最初に下から始まる価格帯が近いアイテムを提供します。左結合で上から始まる最も近い価格帯を持つ別のアイテムとリンクするか、そうでない場合は範囲​​の上または後ろから選択するセレクターを配置できますこれは中途半端な解決策にすぎませんが、うまくいき、多くの検索アルゴリズムがそのようなものを実装しています. 頭を絞るとJOINUNION、 、 などでクエリをリンクして、必要なものに近いものを見つけることができます. mysqlLIMITのそれらのエントリを確認してください.マニュアル

JOIN3 番目に、 ..を使用ON NOT NULLして検索条件を追加することもできます。これを見てください(そして、結合の使い方がわからない場合は、これを見てください)

最後に、 PDOに慣れることをお勧めします。これは、PHP で適切なデータベース クエリを実行するための最良の方法です。

于 2012-07-18T21:14:05.933 に答える
2

これは実際にはクエリ構文の問題ではありません。ここでの問題は、「ベスト マッチ」と見なされるものをアプリケーションに定義することです。このような関数には、単純に最適なものはありません。自分で定義する必要があります。それができたら、実装に取り​​掛かることができます。

簡単な例として、"ベスト マッチ" を、可能な限り多くの明示的なクエリ パラメータが一致し、int 値のパラメータが可能な限り一致するものとして定義できます。次に、各一致の「スコア」を計算し、それで並べ替えることができます。

したがって、検索が であるとしますfood=BBQ, fastfood=Yes, price=2。クエリは次のようになります。

SELECT *,
    SUM(
        food=:food, -- if food matches, add one to score
        fastfood=:fastfood, -- if fastfood matches, add one to score
        -- finally, add 2 for an exact price match, 1 for off-by-one price match,
        -- 0 for off-by-two matches, etc
        (SELECT MAX(price)-1 from foods)-ABS(price-:price) 
    ) AS score
    FROM foods ORDER BY score DESC

スコアに追加する量を調整することで、各試合の重要度を調整できます。また、カテゴリ間に異なる「距離」があるかどうかを判断できます。たとえば、「ステーキハウス」は「アメリカン」よりも「BBQ」に近いので、ステーキハウスの場所のスコアが高くなるはずです。

これは簡単な方法ですが、行ごとにスコアを計算する必要があるため、効率が悪い場合があります。複数のクエリを使用して高速化できます。最初に完全一致を探します。何も見つからない場合は、部分一致のすべての行のスコアを計算します。それでも何も見つからない場合にのみ、テーブル全体の検索に戻ります。

SELECT * FROM foods WHERE food=:food AND fastfood=:fastfood AND price=:price;
-- if no matches then:
SELECT *, SUM(food=:food, fastfood=:fastfood, (SELECT MAX(price)-1 from foods)-ABS(price-:price)) AS score
WHERE food=:food OR fastfood=:fastfood OR price=:price ORDER BY score DESC
于 2012-07-18T21:34:56.030 に答える
1

MySQL を使用している場合は、"match against" 命令を試してみてください。「AND」の代わりに「OR」を使用してください。(対戦は私が考える最良の方法です)

于 2012-07-18T21:01:37.660 に答える
1

まあ、MySQL データベースは、そのようなことを念頭に置いて設計されているわけではありません。当て推量を実行するのではなく、実際に要求した内容を返す必要があります。

残念ながら、これはコードでこのロジックを実装する必要があることを意味します。完全一致を検索し、それが機能しない場合は、特定のアイテムが一致するケースを検索します。

マッチの関連性は、デザイナーであるあなた次第です。

複雑なクエリを組み合わせて目的のデータを取得できないというわけではありません。そのロジックを構築する必要があります (おそらく、さまざまな SELECT ステートメントの結果に対して UNIONS を実行することによって)。

于 2012-07-18T21:03:29.970 に答える