人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

複数のWhere条件がある際に、どの条件に合致したのかSQL(MySQL)中で判断したいと考えています。

以下のテーブル構成があるとします。(投稿&タグ付けできるサイト)

▼postsテーブル
|pid|msg|cnt|
|1|はてなは初心者|100|
|2|今日は良い天気|150|
|3|旅行に行きたい|200|

▼tagsテーブル
|tid|pid|tag|
|1|1|はてな|
|2|1|初心者|
|3|3|旅行|

閲覧者がキーワード検索を行う際、postsテーブルのmsgとtagsテーブルのtagを対象に、どちらに合致したかによって係数を変えてスコア付けして、スコア順にソートした結果を得たいと考えています。
↓間違ったSQLですがイメージとしてはこのようなことを実現したいのです。

select distinct p.*, p.cnt * (if msgに合致=1 else tagに合致=2) as SCORE
from posts as p left join tags as t on p.pid=t.pid
where p.msg like ? or t.tag like ? order by SCORE desc

どうすれば良いのか、皆さんのお知恵を頂ければ嬉しいです。

●質問者: puuyan
●カテゴリ:インターネット ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● きゃづみぃ
ベストアンサー

それぞれ別のSQLにし、それをUNIONすれば いいだけかと思います。


puuyanさんのコメント
taknt様 大変ありがとうございます。 恥ずかしながらUNIONという命令をはじめて知りました。 早速実験してみました。ほとんど希望通りなのですが、一つ問題が。。。 msgとtagのどちらの条件にも合致する場合、当該レコードが2行抽出されてしまうのです。(SCOREの値をselectしていますので当然と言えば当然なのですが...) 係数値の高いtagの方を優先して1行のみの抽出にしたいのですが、こういったことは可能でしょうか? (むしろ、諸々含めてPHP側で処理してしまうのが良いでしょうか?) 細かい内容で恐縮です。お知恵をお借りできれば嬉しいです。 ▼現在のSQL (select distinct p.*, p.cnt * 1 as SCORE from posts as p left join tags as t on p.pid=t.pid where p.msg like ?) union (select distinct p.*, p.cnt * 2 as SCORE from posts as p left join tags as t on p.pid=t.pid where t.tag like ?) order by SCORE desc

puuyanさんのコメント
すみません、書き忘れました。 SCORE値のselectは必須ではないのですが、どちらの検索条件に合致したレコードなのかのフラグ情報は得たいと考えています。(最終的な画面表示の際に利用いたします。) 本当に細かい内容で恐縮です。

きゃづみぃさんのコメント
unionの結果を絞りこむというのは、どうでしょうか?

きゃづみぃさんのコメント
Distinct でもいいかもしれませんが。

puuyanさんのコメント
ありがとうございます。 実験してみまして以下のようなSQLでどちらのwhere条件に合致したかのフラグ情報が取れました。(重複レコードもなくせました。) なんとかなりそうです。 細かい内容にも関わらず、色々とありがとうございました。 感謝! select uni.pid, uni.msg, sum(uni.FLAG) as TAG_FLAG from ( (select p.*, 0 as FLAG from posts as p left join tags as t on p.pid=t.pid where p.msg like ?) union (select p.*, 1 as FLAG from posts as p left join tags as t on p.pid=t.pid where t.tag like ?) ) as uni group by uni.pid order by TAG_FLAG desc
関連質問

●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ