sql >> データベース >  >> RDS >> Mysql

各キーワードの上位「n」の結果

    resultsのスキーマを指定していないため 、これまたは非常に類似していると思います(おそらく余分な列):

    create table results (
      id int primary key,
      user int,
        foreign key (user) references <some_other_table>(id),
      keyword varchar(<30>)
    );
    

    ステップ1: keyword/userで集計 クエリの例と同じですが、すべてのキーワードについて:

    create view user_keyword as (
      select
        keyword,
        user,
        count(*) as magnitude
      from results
      group by keyword, user
    );
    

    ステップ2: 各キーワードグループ内の各ユーザーをランク付けします(行をランク付けするためのサブクエリの使用に注意してください):

    create view keyword_user_ranked as (
      select 
        keyword,
        user,
        magnitude,
        (select count(*) 
         from user_keyword 
         where l.keyword = keyword and magnitude >= l.magnitude
        ) as rank
      from
        user_keyword l
    );
    

    ステップ3: ランクが特定の数値よりも小さい行のみを選択します:

    select * 
    from keyword_user_ranked 
    where rank <= 3;
    

    例:

    使用される基本データ:

    mysql> select * from results;
    +----+------+---------+
    | id | user | keyword |
    +----+------+---------+
    |  1 |    1 | mysql   |
    |  2 |    1 | mysql   |
    |  3 |    2 | mysql   |
    |  4 |    1 | query   |
    |  5 |    2 | query   |
    |  6 |    2 | query   |
    |  7 |    2 | query   |
    |  8 |    1 | table   |
    |  9 |    2 | table   |
    | 10 |    1 | table   |
    | 11 |    3 | table   |
    | 12 |    3 | mysql   |
    | 13 |    3 | query   |
    | 14 |    2 | mysql   |
    | 15 |    1 | mysql   |
    | 16 |    1 | mysql   |
    | 17 |    3 | query   |
    | 18 |    4 | mysql   |
    | 19 |    4 | mysql   |
    | 20 |    5 | mysql   |
    +----+------+---------+
    

    キーワードとユーザーでグループ化:

    mysql> select * from user_keyword order by keyword, magnitude desc;
    +---------+------+-----------+
    | keyword | user | magnitude |
    +---------+------+-----------+
    | mysql   |    1 |         4 |
    | mysql   |    2 |         2 |
    | mysql   |    4 |         2 |
    | mysql   |    3 |         1 |
    | mysql   |    5 |         1 |
    | query   |    2 |         3 |
    | query   |    3 |         2 |
    | query   |    1 |         1 |
    | table   |    1 |         2 |
    | table   |    2 |         1 |
    | table   |    3 |         1 |
    +---------+------+-----------+
    

    キーワード内でランク付けされたユーザー:

    mysql> select * from keyword_user_ranked order by keyword, rank asc;
    +---------+------+-----------+------+
    | keyword | user | magnitude | rank |
    +---------+------+-----------+------+
    | mysql   |    1 |         4 |    1 |
    | mysql   |    2 |         2 |    3 |
    | mysql   |    4 |         2 |    3 |
    | mysql   |    3 |         1 |    5 |
    | mysql   |    5 |         1 |    5 |
    | query   |    2 |         3 |    1 |
    | query   |    3 |         2 |    2 |
    | query   |    1 |         1 |    3 |
    | table   |    1 |         2 |    1 |
    | table   |    3 |         1 |    3 |
    | table   |    2 |         1 |    3 |
    +---------+------+-----------+------+
    

    各キーワードの上位2つのみ:

    mysql> select * from keyword_user_ranked where rank <= 2 order by keyword, rank asc;
    +---------+------+-----------+------+
    | keyword | user | magnitude | rank |
    +---------+------+-----------+------+
    | mysql   |    1 |         4 |    1 |
    | query   |    2 |         3 |    1 |
    | query   |    3 |         2 |    2 |
    | table   |    1 |         2 |    1 |
    +---------+------+-----------+------+
    

    同点がある場合(例のキーワード「mysql」についてはユーザー2と4を参照)、同点のすべてのパーティが「最後の」ランクを取得します。つまり、2番目と3番目が同点の場合、両方にランク3が割り当てられます。

    パフォーマンス:キーワードとユーザー列にインデックスを追加すると役立ちます。同様の方法でクエリされているテーブルがあり、2つの列に4000と1300の異なる値があります(600000行のテーブル)。次のようにインデックスを追加できます:

    alter table results add index keyword_user (keyword, user);
    

    私の場合、クエリ時間は約6秒から約2秒に短縮されました。



    1. php、mysql、jquery、ajaxを使用してdivスクロールにデータを動的にロードする

    2. PHP MySql(1045)ユーザーのアクセスが拒否されました

    3. CakePHPで[イベント]->[スケジュール]->[開始日と終了日の間の日付]ですべてのイベントを選択します

    4. 中括弧とワイルドカードでエスケープするOracleテキスト