2

この質問が冗長ではないことを願っています。私が達成しようとしているのは、ユーザーにページ上のチェックボックスの束を選択させ、一致する行がない場合は最も一致するレコードを返すようにすることです。例えば:

人が[x]リンゴ[x]オレンジ[x]梨[x]バナナをチェックオフします

しかし、テーブルは次のようになります。

Apples     Oranges      Pears     Bananas
 1             1           1        null
 1             1         null       1
 1             1         null       null

(明らかに、ここでid列を見逃しましたが、あなたは私が思うポイントを取得します。)したがって、望ましい結果は、これらの3つの行がほとんどの一致の順序で返されることであり、現在の順序とほぼ同じです。このようなことをするための最善のアプローチが何であるかはわかりません。全文検索であるレーベンシュタイン関数を検討しましたが、完全一致が存在する場合はそれを返すというアイデアが本当に気に入っています。必要がなければ、コードを詳しく説明する必要はありません。私は正しい方向に送られることを望んでいます。このような他の質問を見たことがありますが、どちらに進むべきかまだわかりません。

ありがとう!

4

4 に答える 4

2

一致した列の数を合計し、この合計で行を並べ替えるクエリを作成します。例えば

SELECT *
FROM mytable
ORDER BY COALESCE(Apples, 0) = $apples + COALESCE(Oranges, 0) = $oranges + ... DESC
于 2012-10-31T23:05:02.687 に答える
1

点数順で並べるのは簡単…

SELECT fb.ID, fb.Apples, fb.Oranges, fb.Pears, fb.Bananas
FROM FruitBasket fb
ORDER BY
  CASE WHEN @Apples = fb.Apples THEN 1 ELSE 0 END
  + CASE WHEN @Oranges = fb.Oranges THEN 1 ELSE 0 END
  + CASE WHEN @Pears = fb.Pears THEN 1 ELSE 0 END
  + CASE WHEN @Bananas = fb.Bananas THEN 1 ELSE 0 END
  DESC, ID

ただし、これによりテーブルスキャンが発生します (TOP を使用しても)。最後のレコードは、これまでに見つかったレコードよりも一致する可能性があるため、すべてのレコードを読み取る必要があります。


このようなタグ付けシステムを検討できます

Content --< ContentTag >-- Tag

次のように照会されます。

SELECT ContentID
FROM ContentTag
WHERE TagID in (334, 338, 342)
GROUP BY ContentID
ORDER BY COUNT(DISTINCT TagID) desc

このクエリでは、ContentTag.TagId のインデックスが使用されます。

于 2012-10-31T23:47:49.083 に答える
0

チェックボックス/データ一致の合計で降順

SELECT * FROM table
ORDER BY (COALESE(Apple,0) * @apple) + (COALESE(Orange,0) * @orange) ..... DESC

@apple / @orange はユーザーの選択を表します: 1 = チェック済み、0 = チェックなし

于 2012-10-31T23:42:35.603 に答える
0

これはかなり単純ですが、IFNULL()(MySQL または DB の同等物) を使用して一致の合計を返し、それをORDER BY

// columns and weighting score
$types = array("oranges"=>1, "apples"=>1, "bananas"=>1, "pears"=>1);
$where = array();
// loop through the columns
foreach ($types as $key=>&$weight){
    // if there is a match in $_REQUEST at it to $where and increase the weight
    if (isset($_REQUEST[$key])){
        $where[] = $key . " = 1";
        $weight = 2;
    }
}
// build the WHERE clause
$where_str = (count($where)>0)? "WHERE " . implode(" OR ", $where) : "";

// build the SQL - non-null matches from the WHERE will be weighted higher
$sql = "SELECT apples, oranges, pears, bananas, ";
foreach ($types as $key=>$weight){
    $sql .= "IFNULL({$key}, 0, {$weight}) + ";
} 
$sql .= "0 AS score FROM `table` {$where_str} ORDER BY score DESC";

「オレンジ」と「リンゴ」が選択されていると仮定すると、SQL は次のようになります。

SELECT apples, oranges, pears, bananas, 
IFNULL(apples, 0, 2) + IFNULL(oranges, 0, 2) + IFNULL(pears, 0, 1) + IFNULL(bananas, 0, 1) + 0 AS score 
FROM `table` 
WHERE oranges = 1 OR apples = 1 
ORDER BY score DESC
于 2012-10-31T23:07:46.583 に答える