2

2 回の FULLTEXT 検索で、本のタイトルとタグに含まれる検索用語を探し、次の結果を取得します。

rScore tScore ID
...
1.235689725827653 0 406
0.928482055664062 2.37063312530518 406
0.928482055664062 0 406
0.453363467548853 0 520
...

私が望んでいることは、すべての重複した ID が連結され、最高のスコアが取得されたことです。

rScore tScore ID
...
1.235689725827653 2.37063312530518 406
0.453363467548853 0 520
...

、ただし GROUP BY の後、ID 406 はこの行の列にグループ化されました。

...
MATCH_SCORE_TITLE MATCH_SCORE_TAGS ID
0.928482055664062 0 406
0.453363467548853 0 520
...

これらすべての結果をグループ化し、各 MATCH の最大値を維持するにはどうすればよいですか? これは以前に質問されており、JOIN で実行できることは知っていますが、2 つの行の組み合わせでは見つかりませんでした。さらに、TITLE と TAGS が 2 つの異なるテーブルにあるため、クエリに既に JOINS があります。

更新: 「registrants」(検索するタイトルのある左側のテーブル)、「registrants_tags」(左側のテーブルと右側のテーブルの間のリレーショナル テーブル)、および「tags」(検索するタグのある右側のテーブル) の 3 つのテーブルがあります。以下は、SQL クエリの簡略化されたバージョンです。


SELECT
 tags.tag,    (Also tried (GROUP_CONCAT(`tags`.`tag`) AS tags)
 MAX(MATCH(registrants.story_title) AGAINST('bob')) as rScore,
 MAX(MATCH(tags.tag) AGAINST('bob')) as tScore,
 registrants.id, registrants.story_title
FROM registrants 
LEFT JOIN registrants_tags ON registrants.id = registrants_tags.registrant 
LEFT JOIN tags ON registrants_tags.tag = tags.id
WHERE MATCH(registrants.story_title) AGAINST('bob')
 OR MATCH(tags.tag) AGAINST('bob')
GROUP BY registrants.id
ORDER BY (rScore + tScore) DESC

「#1247 - Reference 'tscore' not supported (reference to group function)」というエラー メッセージが表示されます。

4

4 に答える 4

2

スコアで並べ替えmax、サブクエリで a を使用して、最終的な優先行を取得できます。

例えば:

SELECT  id, story_title,
    max(match_score_title) as titleScore,
    max(match_score_tags) as as tagScore
FROM (
    SELECT
        MATCH(registrants.story_title) AGAINST('bob') as rScore,
        MATCH(tags.tag) AGAINST('bob') as tScore,
        registrants.id, registrants.story_title
    FROM
    registrants 
    LEFT JOIN registrant_tags on registrant_tags.registrant=registrant.id
    LEFT JOIN tags on tags.id=registrant_tags.tag
    WHERE rScore > 0 or tScore > 0
) AS score_matcher
group by ID
ORDER BY (rScore + tScore) DESC

それはあなたのために働くはずです。サブクエリに依存しているため、宇宙で最も速いクエリではないかもしれません.MySQLでは私の経験ではあまり最適化されていませんが、結果が得られるはずです.

group_concat次のように利用するために、別のサブクエリに作り直すこともできます。

SELECT
    MATCH(registrants.story_title) AGAINST('bob') as rScore,
    MATCH(tags.tag) AGAINST('bob') as tScore,
    registrants.id, registrants.story_title
FROM
registrants 
LEFT JOIN (
    FROM rtags.registrant, GROUP_CONCACT(DISTINCT tags.tag SEPARATOR ',') as tags
    FROM registrants_tags AS rtags
    INNER JOIN tags on tags.id=registrants_tags.id
    GROUP BY rtags.registrant
) AS grouped_tags ON registrants.id = grouped_tags.registrant 
WHERE rScore > 0 or tScore > 0
ORDER BY (rScore + tScore) DESC

データベースで「grouped_tags」フィールドを登録者テーブルに追加すると、フルテキスト インデックスが追加され、grouped_tags サブクエリが不要になります。その後、誰かが特定の登録者のタグを更新するたびに、grouped_tags フィールドが正しいタグの現在のリストで更新されます。

また、grouped_tags フィールド (インターフェイスに入力される) を追加することについて私が推奨したようにすれば、クエリ全体をこれに置き換えることができ、フルテキスト インデックスを使用するとかなり高速になります (ただし、フルテキスト インデックスでは MyISAM を使用する必要があります。まったく素晴らしいとは言えません)。

あなたがそれをしたなら、これは間違いなく私がここにリストした最速のクエリになるでしょう.

SELECT
    MATCH(story_title) AGAINST('bob') as rScore,
    MATCH(grouped_tags) AGAINST('bob') as tScore,
    id, story_title
FROM
registrants 
WHERE rScore > 0 or tScore > 0
GROUP BY ID
ORDER BY (rScore + tScore) DESC

したがって、このクエリを実行するための推奨事項は山ほどあります。どのソリューションを使用するかは、データ セットのサイズと、必要なクエリの速度に大きく依存します。ベンチマークを行って、どれが最適かを見つけることをお勧めします

于 2012-09-25T04:25:18.857 に答える
2
SELECT MATCH_SCORE_TITLE, MAX(MATCH_SCORE_TAGS), ID FROM <tablename>........GROUP BY ID
于 2012-09-25T04:25:32.460 に答える
0

ORDER BY MATCH_SCORE_TITLE および MATCH_SCORE_TAGS で SELECT DISTINCT ID を使用できます。

于 2012-09-25T04:18:57.923 に答える
0

このパターンを試してみてください:

SELECT
    *
FROM registrants r1
LEFT JOIN registrants t2 ON r1.id = r2.id AND r1.MATCH_SCORE_TITLE > r2.MATCH_SCORE_TITLE
LEFT JOIN registrants_tags ON r1.registrants.id = registrants_tags.registrant 
LEFT JOIN tags ON registrants_tags.tag = tags.id
WHERE
    r2.id IS NULL AND
    (MATCH(r1.registrants.full_name) AGAINST('bob')
    OR MATCH(tags.tag) AGAINST('bob'))
ORDER BY (tscore + ascore) DESC

別の回答LEFT JOINでトリックの簡単な説明を参照してください。

編集:不要な GROUP BY 句を削除しました。

于 2012-09-25T14:48:12.023 に答える