0

ここで質問するのは初めてです

基本的に、顧客の基本データを格納するテーブル、質問に基づくユーザー属性を格納するテーブル、同じ属性の複数のオプションを格納するユーザー設定を格納するテーブルが 3 つあります。

まあ言ってみれば...

表のユーザー:

userid, username, useremail, userphone

テーブル属性:

attributeid,attributeofuser, attributename(number), attribute value(number)

テーブル設定:

preffid, preffofuser, preffattributename(number), preffattributevalue(number)

attributename と attributevalues は、別のテーブルに格納されている属性と値の ID の番号です。

preffattributevalue が 0 の場合、それは問題ではないことを意味するため、どの属性でも問題ありません

だから私が必要とするのは、属性に基づいて特定のユーザーの好みに一致するすべてのユーザーを見つけ、それをパーセンテージでも行うことです。

私は、非常に重く見えるクエリのループを実行し、より良いオプションを探していることに気づきました。前もって感謝します

4

2 に答える 2

1

Marty McVry が言ったように、これは興味深いクエリです。これが私の解決策です。テーブルの名前を少し自由に変更したことに注意してください...

スキーマ:

CREATE TABLE user (id int, username varchar(200), info varchar(200));
CREATE TABLE attr (id int, user_id int, a_name varchar(200), a_value varchar(200));
CREATE TABLE pref (id int, user_id int, pa_name varchar(200), pa_value varchar(200));

クエリ:

SELECT looker.username AS looker_name, 
    CONCAT("likes ",match_candidate.username,"\'s") AS candidate_name, 
    GROUP_CONCAT(" ", CONCAT(attr.a_value," ", attr.a_name)) AS attributes,
    COUNT(attr.a_name) AS match_count
FROM pref 
  INNER JOIN attr ON attr.a_name = pref.pa_name 
  INNER JOIN user AS match_candidate ON match_candidate.id = attr.user_id
  INNER JOIN user AS looker ON looker.id = pref.user_id
WHERE (pref.pa_value IS NULL OR pref.pa_value = attr.a_value) AND
  pref.user_id = 101 AND looker.id <> match_candidate.id
GROUP BY candidate_name
ORDER BY match_count DESC;

説明:

pref テーブルを取得し、それを attr テーブルと結合して、一致する属性名を取得します。attr テーブルを user テーブルと結合して、候補の名前を取得できます。最後に、「見ている人」、つまり自分の好みを一致させたいユーザーに接続できます。これは、ユーザー テーブルとの 2 番目の結合によって行われますが、今回はもちろん pref.user_id で行われます。ここで、一致しない属性値を整理する必要があります。これを行うには、すべての結果行が設定属性値として NULL を持つか、その属性値が一致する候補の属性値と等しい (結合条件によって属性名が既に一致している) ことを強制します。特定の「looker」の一致する候補を取得するには、これもWHERE句 ( pref.user_id = 101) に含める必要があります。ここ101は、1 人のユーザー ID の単なる例です。最後に、見ている人を自分自身と一致させないようにする必要があります (自分の好みが自分の属性と一致する場合)。フィールドは、 使用する一致する属性を組み合わせるために、SELECT少しいじっています。GROUP_CONCATCONCATGROUP BY

私は遊ぶためにsqlfiddleを作りました。そのため、私の例では、文字列を属性名と値として使用しました。pref 値の NULL は、優先度がないことを意味し、候補のすべての属性値が一致することを意味します。

補足: attr と pref に同じテーブルを使用し、そのタイプを定義するフィールドを追加できます。

追記:この回答をかなり更新しました。以前のバージョンのフィドルをチェックアウトした場合は、リンクが変更されている可能性があるため、もう一度リンクをたどってください。

于 2013-04-28T09:53:39.413 に答える
0

面白い問題...

以下のクエリはテストされていないため、機能するかどうかはわかりません。

    SELECT u.*,
           sub.num_match
      FROM users AS u
INNER JOIN (   SELECT a.attributeofuser AS uid,
                      COUNT(a.attributeid) AS num_match
                 FROM preferences AS p
            LEFT JOIN attributes AS a
                   ON p.preffattributename = a.attributename
                WHERE p.prefofuser = $user_id
                  AND p.prefofuser <> a.attributeofuser
             GROUP BY a.attributeofuser                      ) sub
        ON u.userid = sub.uid
  ORDER BY sub.num_match DESC;

まず、サブクエリは、要求しているユーザーのプリファレンスと共通する属性を少なくとも 1 つ持つユーザーのすべてのユーザー ID を取得します。また、共通する属性の数も返されるため、後で一致率を計算できます。

サブクエリからのデータを使用して、テーブルからユーザー データを取得できますusers

別のクエリを使用して、要求しているユーザーが入力した設定の数を取得すると、一致率を計算できます!

于 2013-04-28T09:15:59.083 に答える