2011-10-29 4 views
3

私のサイトでは、ユーザーが好きなものを選択することができます。これは、あらかじめ定義されたドロップダウンメニューを使用して行われるため、ユーザーがログインするたびに彼らは彼らと同じ関心を持っているユーザーのリストを入手します。PHP - MySQL Searchデータベーステーブルの返品率がパーセント一致

これは、MySQL WHERE句を使用して、ログインしたユーザーの関心事(データベースに格納)を取り、サイト上の他のユーザーと一致させることによって行われます。しかし、私が問題を抱えているのは、各ユーザーの横にパーセンテージやスコアを表示して、ログインしたユーザーの興味にどれほど近いかを示す方法です。例えば

:あなたの興味

  • user2が30%一致 - - - あなたの興味
  • USER1〜60%の一致

    • user1のご関心に20%の一致

    すべてのユーザーが100%一致した場合、それぞれのユーザーは5つの異なる興味を持っています。

    テーブル構造のサンプル:

    CREATE TABLE IF NOT EXISTS `helloworld` (
        `id` int(9) NOT NULL AUTO_INCREMENT, 
        `like1` varchar(300) NOT NULL, 
        `like2` varchar(300) NOT NULL, 
        `like3` varchar(300) NOT NULL, 
        `name` varchar(300) NOT NULL, 
        PRIMARY KEY (`id`) 
    ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ; 
    

    例クエリ:

    SELECT * FROM helloworld WHERE like1='football' AND like2='art' 
    

    私はCOUNT機能を使用して考えていたが、私はわからないのですか?サブクエリを使用する必要がありますか?

    編集:私はサーバー側の言語のためにPHPを使用しています。ユーザーは自分の好きなものを入力することはできません。あらかじめ定義されたリストを使用する必要があります。

  • +1

    like1 = 'art'とlike2 = 'football'の場合、上記の例のクエリと一致しますか? – Sparky

    +0

    申し訳ありませんが、あなたはlike2の列には常にlike1のアートは一致しません。ユーザーは、自分の好きなものを入力したり組み合わせたりすることはできません。あらかじめ定義されたリスト(ドロップダウンメニュー)から選択する必要があります。このサイトはphpとmysqlを使って実装されています。 – TheDeveloper

    答えて

    0

    ここで私はそれをやっています。 $ like1、$ LIKE2と仮定し、$ like3は、現在のユーザーからの値です:これは、あなたの現在のスキーマでそれを行うだろう

    SELECT (IF(like1='$like1',1,0) + IF(like2='$like2',1,0) + IF(like3='$like3',1,0))/3*100 match_percent, 
    COUNT(id) 
    FROM helloworld 
    GROUP BY match_percent; 
    
    +0

    あなたは、(間違って)あなたが好きなものが同じ列に格納されていると仮定しています。これは、データベース内の好きな人の総数をわずか5に制限します。 – Bohemian

    +0

    私はポスターに尋ねたはずですが、前提は必ずしも無効であるとは限りません。ですから、各列にはすべての選択肢が用意されていますか?それぞれが異なる場合、私のコードは問題ありません。そうでなければ、より正規化されたソリューションが必要になります。 – davidethell

    +0

    正しいすべての値は、各列ごとに異なります。あなたのコードをテストして、私が探している結果を生み出すようです。しかし、何らかの理由で常に0%のユーザーを返します。 – TheDeveloper

    0

    あなたはユーザーと好きな人との間に多岐にわたる関係があります。あなたのテーブルは1NFに違反しています - like列の「繰り返しグループ」があります。 - 私は:)

    ヒントを動作するようにあなたにそれを残しておきます

    create table user_likes (
        user_id int(9) NOT NULL, 
        like_name varchar(300) NOT NULL 
    ); 
    

    今、あなたはマッチの数を取得する単純なクエリを使用することができます。代わりに、これを処理するために別の関連テーブルを持っています:ビットマスクを使用して一致を判断し、like_name(helpはlike_namesテーブル)のそれぞれに2の数値の事前定義された累乗を割り当てることができます。

    0

    まず、別のスキーマが必要だと思います。あなたが持っているものは、十分に柔軟ではないので、あなたの仕事を非常に困難にします。私はこのようなものをお勧めします。

    CREATE TABLE `users` (
        `id`  INT NOT NULL AUTO_INCREMENT, 
        `name`  VARCHAR(300) NOT NULL, 
        PRIMARY KEY (`id`) 
    ); 
    
    CREATE TABLE `likes` (
        `user`  INT NOT NULL, 
        `interest` VARCHAR NOT NULL, 
        PRIMARY KEY (`user`,`interest`) 
    ); 
    

    (申し訳ありませんが、私はMySQLでのFKの関係を設定する方法を覚えていないが、私はあなたが簡単に十分なことを把握することができます確信しています。その後)

    、ユーザーごとに「好き」の数を決定する:

    SELECT COUNT(*) 
    FROM users 
    JOIN likes ON likes.user=users.id 
    WHERE users.name = 'bob'; 
    

    その後、2人のユーザーが共通しているのが好き何を決定するために:次に、これらの3に基づく

    SELECT COUNT(*) 
    FROM users AS u1 
    JOIN likes AS l1 ON (l1.user = u1.id) 
    JOIN likes AS l2 ON (l1.interest = l2.interest) 
    JOIN users AS u2 ON (l2.user = u2.id) 
    WHERE u1.name = 'bob' 
        AND u2.name = 'alice'; 
    

    あなたのクライアントコードの中にあなたが望むようにあなたのパーセンテージを計算することができますが、必要に応じてすべてのSQL側でサブ選択を行うことができます。

    例:

    USERS: 
    id | name 
    ----+------- 
        1 | bob 
        2 | alice 
    
    LIKES: 
    user | interest 
    ------+---------- 
        1 | fish 
        1 | baseball 
        2 | fish 
        2 | cooking 
        2 | baseball 
    

    そのボブが興味を持っている、とアリスは関心を持っていることが表示されますbobaliceのための最初のクエリを実行しています。次に、2番目のクエリを実行すると、bobとaliceが一緒に共有の関心を持つことが示されます。

    アリスが自分の興味の100%(2/2 = 100%)を共有していることをボブに示し、ボブが自分の興味の66%(2/3 = 66%)を共有していることをアリスに示すことができます。

    0

    PHPレベルで確認してください。各ユーザーの関心を考慮して、array_intersect()の結果に対してcount()を使用して得点を得て、ビジターと他のユーザーの関心を比較することができます(http://www.php.net/manual/en/function.array-intersect)。 PHP)。 5つの関心を許すならば、それは(5 * count(array_intersect({{{{params}})))%です。マッチしない場合は0%、4マッチの場合は80%。

    0

    select 
        t2.id, 
        t2.name 
        sum(
         t1.like1 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) + 
         t1.like2 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) + 
         t1.like3 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) + 
         t1.like4 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) + 
         t1.like5 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) 
        ) * 20 as percent_match 
    from helloworld t1 
    left join helloworld t2 on t1.id != t2.id 
    group by 1, 2 
    order by 3 desc; 
    

    MySQLでtrue1あるので、これは動作します - 真理を合計すると、マッチの数が合計されます。

    +0

    * 20を使う目的は? t1.like2から(t2.like1、t2.like2、t2.like3、t2.like4、t2のいずれか)。like5) - 2行目は動作していないようです。あなたは上記のそれぞれを別々に集計すべきだと思いますか? – TheDeveloper

    +0

    @TheDeveloper '* 20'はパーセンテージに変換するために使用されます。 'SUM()'は '0'と' 5 'の間に数字を与えますが、 '0'と' 100'の間にパーセンテージが必要です。したがって '* 20'です。また、コンマの代わりに点(つまり構文エラー)がありました。今すぐ試してみてください。 – Bohemian

    +0

    構文エラーがまだ終了する、私はそれを動作させることができませんでした。あなたのMySQLサーバーバージョンに対応するマニュアルをチェックして、正しい構文が「sum(t1.like1、t2.like2、t2.like3、t2.like4、t2.like5)ライン4 " – TheDeveloper