sql >> Database teknologi >  >> RDS >> Mysql

Top 'n' resultater for hvert søgeord

Da du ikke har givet skemaet for results , jeg antager, at det er denne eller meget lignende (måske ekstra kolonner):

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

Trin 1: samle efter keyword/user som i din eksempelforespørgsel, men for alle søgeord:

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

Trin 2: ranger hver bruger inden for hver søgeordsgruppe (bemærk brugen af ​​underforespørgslen til at rangere rækkerne):

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
);

Trin 3: vælg kun de rækker, hvor rangeringen er mindre end et tal:

select * 
from keyword_user_ranked 
where rank <= 3;

Eksempel:

Anvendte basisdata:

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   |
+----+------+---------+

Grupperet efter søgeord og bruger:

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 |
+---------+------+-----------+

Brugere rangeret inden for søgeord:

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 |
+---------+------+-----------+------+

Kun top 2 fra hvert søgeord:

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 |
+---------+------+-----------+------+

Bemærk, at når der er uafgjort -- se brugere 2 og 4 for søgeordet "mysql" i eksemplerne -- får alle parter i uafgjort den "sidste" rang, dvs. hvis 2. og 3. er lige, tildeles begge rang 3.

Ydeevne:Tilføjelse af et indeks til søgeords- og brugerkolonnerne vil hjælpe. Jeg har en tabel, der forespørges på en lignende måde med 4000 og 1300 forskellige værdier for de to kolonner (i en tabel med 600.000 rækker). Du kan tilføje indekset sådan her:

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

I mit tilfælde faldt forespørgselstiden fra omkring 6 sekunder til omkring 2 sekunder.



  1. MariaDB 10 CentOS 7 flytte datadir ve

  2. Variationer i PostgreSQL LIKE-forespørgselsydeevne

  3. Generer en tilfældig dato i Oracle med DBMS_RANDOM

  4. Hvordan får man alle privilegier tilbage til root-brugeren i MySQL?