2

mysql データベースにユーザー プロファイルのテーブルがあり、フィールドの 1 つはSETユーザーのグループを追跡する列です。

テーブル構造は次のとおりです。

CREATE TABLE IF NOT EXISTS `users_profiles` (
  `userId` mediumint(9) NOT NULL DEFAULT '0',
  `birthday` date DEFAULT NULL,
  `groups` set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20')
 );

ソートされた降順リストで最も人気のあるグループを取得したいのですが、SET列を使用したという事実により、 などの関数を使用するのが少し難しくなりますCOUNT

次のクエリを実行すると、特定のグループ数を取得できます。

SELECT count(NULLIF(`interests` & 1,0)) as Count1stVal FROM users_profiles;

ただし、グループごとにクエリを実行してから、最も人気のあるグループを計算したくありません

4

2 に答える 2

1

このようなものが機能するはずです:

SELECT 
    groups, # get the group number
    COUNT(groups) AS group_cnt # use this for sorting
FROM users_profiles
GROUP BY groups
ORDER BY group_cnt DESC

このマシンにはサーバーがないため、テストできませんが、期待どおりに動作するはずです。

編集:クエリは、グループ列に値が1つしかない場合にのみ機能します。

グループがセット内の番号に対応するIDを持つエントリとしてリストされる別のテーブルがある場合は、次のようにすることができます。

SELECT
    g.id, # the group id corresponds to the groups in the set
    COUNT(up.userId) as g_cnt # count the number of users with the group
FROM (
    users_profiles up,
    groups g
)
WHERE
    FIND_IN_SET(g.id, up.groups) > 0
GROUP BY g.id
ORDER BY g_cnt DESC

ただし、グループテーブルを導入する場合は、これをユーザーとグループ間の多対多の関係に正規化するのが最適な場合があります。

于 2012-06-28T19:38:15.227 に答える
1

提案がありますが、実際のコードではありません (設定されたデータ型に慣れていないため)。

最初に、セットの要素ごとに 1 つの行を持つ一時テーブルまたはサブクエリを作成します。各行のセットには、まさにその要素が含まれます。これを要素と呼びます。

次に、次のクエリを実行します。

select e.element, count(*)
from user_profiles up join
     Elements e
     on up.groups like concat('%', e.element, '%')
group by e.element
order by 2 desc

ここで、唯一の問題は、設定値が互いに重複することです。つまり、「1」と「10」があるので、これはうまくいきません。これを修正するには、次のいずれかを実行できます。

  1. 設定値の名前を変更します (たとえば、実際のテーブルにはこの問題がない場合があります)。
  2. 「&」操作と生成された数字のリストを使用します。この場合、 on ステートメントは次のように変更されます。

    up.groups & e.element > 0

ページhttp://www.vbmysql.com/articles/mysql/the-mysql-set-datatypeは、セットでできることの概要を説明しています。また、彼らが落胆することが多い理由も説明しています。. . 正規化されたテーブルの機能を提供しないためです。

于 2012-06-28T19:30:51.117 に答える