3

Ok。私のケースをもう少し詳しく説明しようと思います。4 人のユーザーに 6 つの質問 (はい/いいえ) を行い、この回答を文字列変数 (1-はい、0-いいえ) として記録しました。その結果、私は次のようになりました。

CREATE TABLE `answers` (
  `user_id` int(10) unsigned NOT NULL,
  `answers` int(6) DEFAULT NULL,
  PRIMARY KEY (`user_id`)
);
INSERT INTO `answers` VALUES ('1', '111111');
INSERT INTO `answers` VALUES ('2', '111000');
INSERT INTO `answers` VALUES ('3', '110011');
INSERT INTO `answers` VALUES ('4', '100001');

今、「111111」の結果に似た結果を見つけようとしています (すべての質問に「はい」と答えました)。50% 一致する行は興味深いものです。

ユーザー #1 の回答は 100% 一致 111111=111111
ユーザー #2 の回答は 50% 一致 111000 -> 111111
...など

だから私はどのクエリが私のために50%一致する行を見つけるかを発見したい:)

4

3 に答える 3

1

BIT_COUNTが役立つはずです。

SELECT * FROM table WHERE BIT_COUNT(score)>=3;

このクエリは、6 つの質問があり、スコアが 50% 以上のスコアを探すことを前提としています。

このように行を挿入すると

INSERT INTO `answers` VALUES ('1', b'111111');

変換を使用する必要はありません。

より正確には、スコアをそのように挿入すると、それらはバイナリとして扱われ、ビット単位の演算子をうまく使用できます。だからあなたが例えばするなら

SELECT user_id, BIT_COUNT(answers) FROM answers

あなたは正しい答えの数を取得します。所定のスコアから +/- 2 ポイントを取得するには、次のようになります。

SELECT user_id FROM answers WHERE BIT_COUNT(answers) BETWEEN BIT_COUNT(score_to_compare_with)-2 AND BIT_COUNT(score_to_compare_with)+2 
于 2012-12-02T12:15:00.430 に答える
1

OPがスキーマを追加した後、回答を書き直しました。

まず、これは非常に複雑な問題であるため、ストアド関数にカプセル化することが理にかなっています。

DELIMITER ;; -- In case you are using PHPMyAdmin or something like that

-- Calculates the number of matching answers between
-- two users, given the total number of answers each user has made
-- Replace 6 everywhere in this function with the number of questions (if it changes)
CREATE FUNCTION NumberOfMatchingAnswers(p_user1 INT, p_user2 INT) RETURNS INT

BEGIN
DECLARE i INT Default 1; -- Loop counter
DECLARE str_user1 VARCHAR(6); 
DECLARE str_user2 VARCHAR(6); 
DECLARE num_matched_answers INT Default 0;

SET str_user1 = LPAD(p_user1,6,'0');
SET str_user2 = LPAD(p_user2,6,'0');

answer_match_loop : LOOP

    IF SUBSTR(str_user1, i, 1) = SUBSTR(str_user2, i, 1) THEN
        SET num_matched_answers = num_matched_answers + 1;
    END IF;

    SET i = i + 1; -- Basically the equivalent of a FOR loop
    IF i > 6 THEN
        LEAVE answer_match_loop;
    END IF;
END LOOP answer_match_loop;

RETURN num_matched_answers;

END;;

ストアド関数を定義したので、それに基づいてクエリを作成できます。

SELECT user_id FROM Answers WHERE
NumberOfMatchingAnswers(Answers.answers, 101101) >= 3;

このクエリは、3 つ以上の質問でuser_id同じ回答をしたすべての一致する を取得します。101101

では、システムでこのクエリをどのように使用できるでしょうか?

  1. 101101比較したい実際の回答セットに置き換えます
  2. 誤検知が多すぎる場合は3、しきい値が 50% を超えるように数値を増やします。
  3. user_id一致率が 50% を超えるすべての のペアを検索するクエリを作成します。
  4. などなど

: システムを拡張して、yes/no の入力だけでなく、さまざまなオプションを実際に許可する場合は、この保存された関数で対応できます。各桁を比較するため、各質問に対して最大 10 の可能な回答を持つことができ、引き続き機能します。

于 2012-12-02T11:49:33.693 に答える
0

私が話している答えは複雑すぎるかもしれません。ただし、共有するのが最善だと思いました。

24 の質問すべてについて、正解/不正解の順列をパターンとして生成する必要がある場合があります。パターンごとに一意の ID を持つテーブルに保存します。

次に、現在の回答テーブルの列をそのパターン テーブルと照合して、合計、カウントなどを取得します。

言い換えて、サンプルで説明しましょう。このクエリにより、完全一致が得られます。ただし、完全一致がない場合は、部分一致を取得するために必要な変更を行うことができます。

参照先: SQLFIDDLE

あなたのパターンテーブル:

ANSWERS     CONV(BINARY ANSWERS,2,10)
111111      63
111000      56
110011      51
100001      33

あなたの回答表:

ID  ANSWERS
1   111111
2   111000
3   110011
4   100001
5   111000

各一致のカウントを表示するクエリ:

select count(*) into @all from scores;
select x.p as b_answer_pattern,
conv(x.p,10,2) as answer_pattern, 
count(x.id)as counts, 
concat(round((count(x.id)/@all)*100,2),'%') as pct
from (
select id, conv(binary answers,2,10) as p
from scores) as x
group by x.p;

結果:

B_ANSWER_PATTERN    ANSWER_PATTERN  COUNTS  PCT
33                  100001           1      20.00%
51                  110011           1      20.00%
56                  111000           2      40.00%
63                  111111           1      20.00%
于 2012-12-02T18:24:49.040 に答える