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個までと制限できたりできるのかどうか
④②を行った場合に③に満たなかった場合に一致する数を減らしていくことができるか

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

回答の条件
  • 1人2回まで
  • 13歳以上
  • 登録:2012/06/15 18:20:35
  • 終了:2012/06/15 18:56:02

ベストアンサー

id:windofjuly No.1

うぃんど回答回数2625ベストアンサー獲得回数11492012/06/15 18:47:03

ポイント300pt

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を実行して関係ないレコードをプログラム側で除外する方法

他2件のコメントを見る
id:windofjuly

テストをミスっていました。

(4)を訂正します。挙動は回答欄のとおりです。

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 というゴミがまじってるものは無視してください。

2012/06/15 19:19:41
id:shiotaQ

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

2012/06/15 19:29:51
  • id:shiotaQ
    ③その際、レコードの数を10個までと制限できたりできるのかどうかですが、
    一致するレコードが10個以上あった場合を想定しています。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません