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

MYSQLとプログラミングで質問です。

フィールドの種類が、
id,z1,z2,z3,z4,z5,z6,z7,z8,z9,z10
とあるとして、レコードは100個ほどあるとします。
値にはランダムに1?32が入っているとします。

その場合、指定した値(任意のレコード)にid以外で全て一致するレコードを抽出したい場合の構文ですが、

select id from theme_list where z1=26 and z2=12 and z3=16 and z4=20 and z5=12 and z6=26

and z7=10 and z8=15 and z9=19 and z10=10;

になると思います。

この場合の、
?もっと簡単な構文があるかどうか
?全て一致するものがない場合、フィールド内で9個一致するものをフィールドの
順序に関係なく抜き出す方法があるかどうか
?その際、レコードの数を10個までと制限できたりできるのかどうか
??を行った場合に?に満たなかった場合に一致する数を減らしていくことができるか

を知りたいです。
プログラムと組み合わせて利用しないとできないでしょうか。

●質問者: shiotaQ
●カテゴリ:コンピュータ ウェブ制作
○ 状態 :終了
└ 回答数 : 1/1件

▽最新の回答へ

1 ● うぃんど
●300ポイント ベストアンサー

SQLを数行に分けて書いてますが、もちろん一行で書いてもかまいません。

(1)もっと簡単な構文

SELECT id
FROM theme_list
WHERE (z1,z2,z3,z4,z5,z6,z7,z8,z9,z10) = (26,12,16,20,12,26,10,15,19,10)
;

(2)(3)フィールド内で9個一致するものをフィールドの順序に関係なく抜き出す方法
ならびにレコードの数を10個まで制限する方法

SELECT id
FROM theme_list
WHERE (CASE z1 WHEN 26 THEN 1 ELSE 0 END)
 + (CASE z2 WHEN 12 THEN 1 ELSE 0 END)
 + (CASE z3 WHEN 16 THEN 1 ELSE 0 END)
 + (CASE z4 WHEN 20 THEN 1 ELSE 0 END)
 + (CASE z5 WHEN 12 THEN 1 ELSE 0 END)
 + (CASE z6 WHEN 26 THEN 1 ELSE 0 END)
 + (CASE z7 WHEN 10 THEN 1 ELSE 0 END)
 + (CASE z8 WHEN 15 THEN 1 ELSE 0 END)
 + (CASE z9 WHEN 19 THEN 1 ELSE 0 END)
 + (CASE z10 WHEN 10 THEN 1 ELSE 0 END)
 = 9
LIMIT 10
;

(4)満たなかった場合に一致する数を減らしていくこと

SELECT id,
FROM theme_list
ORDER BY 
 (CASE z1 WHEN 26 THEN 1 ELSE 0 END)
 + (CASE z2 WHEN 12 THEN 1 ELSE 0 END)
 + (CASE z3 WHEN 16 THEN 1 ELSE 0 END)
 + (CASE z4 WHEN 20 THEN 1 ELSE 0 END)
 + (CASE z5 WHEN 12 THEN 1 ELSE 0 END)
 + (CASE z6 WHEN 26 THEN 1 ELSE 0 END)
 + (CASE z7 WHEN 10 THEN 1 ELSE 0 END)
 + (CASE z8 WHEN 15 THEN 1 ELSE 0 END)
 + (CASE z9 WHEN 19 THEN 1 ELSE 0 END)
 + (CASE z10 WHEN 10 THEN 1 ELSE 0 END)
LIMIT 10
;

4のSQLには欠点があります。
それは、該当するものが10件に満たない場合、
例えば10個合致するレコードが9件の場合に、
9個合致するレコード1件を回答に含んでしまうこと。

(補足)実際の利用方法

目視対応の例
(4)を実行して、不要なレコードは目視で除外する。

プログラム対応の例
(1)のSQLを実行してダメなら(2)のSQLを実行して、
それでもダメなら(2)の=9を=8に変えて・・・を繰り返す方法

プログラム対応の例その2
(4)のSQLを実行して関係ないレコードをプログラム側で除外する方法


shiotaQさんのコメント
知りたいことをすべて回答していただけました! まずは、じっくり処理を一つ一つ見て自分の理解を深めたいと思います。 ありがとうございます。

shiotaQさんのコメント
4の欠点と言われている処理ですが、一致した数が多い順で10に満たない場合に、次に一致した数が入ってくるというのは、自分の利用目的に合致したものでしたので助かりました。ありがとうございます。

うぃんどさんのコメント
テストをミスっていました。 (4)を訂正します。挙動は回答欄のとおりです。 >|sql| SELECT id, (CASE z1 WHEN 26 THEN 1 ELSE 0 END) + (CASE z2 WHEN 12 THEN 1 ELSE 0 END) + (CASE z3 WHEN 16 THEN 1 ELSE 0 END) + (CASE z4 WHEN 20 THEN 1 ELSE 0 END) + (CASE z5 WHEN 12 THEN 1 ELSE 0 END) + (CASE z6 WHEN 26 THEN 1 ELSE 0 END) + (CASE z7 WHEN 10 THEN 1 ELSE 0 END) + (CASE z8 WHEN 15 THEN 1 ELSE 0 END) + (CASE z9 WHEN 19 THEN 1 ELSE 0 END) + (CASE z10 WHEN 10 THEN 1 ELSE 0 END) AS c FROM theme_list ORDER BY c DESC LIMIT 10 ; ||< 何度もコメントやり直してすみません。 n というゴミがまじってるものは無視してください。

shiotaQさんのコメント
確かに質問の締切はゆっくり行わないと、他の方の回答の用意があった場合に失礼ですね。利用したてなので助言助かります。 前回の質問も早めに締め切ってしまってすみません。 select文の最初の方に、処理がくるんですね。もっと勉強してみます!
関連質問

●質問をもっと探す●



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