sql >> Databáze >  >> RDS >> Mysql

Nejlepší 'n' výsledky pro každé klíčové slovo

Protože jste nezadali schéma pro results , budu předpokládat, že je to toto nebo velmi podobné (možná další sloupce):

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

Krok 1: agregovat podle keyword/user jako ve vašem příkladu dotazu, ale pro všechna klíčová slova:

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

Krok 2: seřadit každého uživatele v každé skupině klíčových slov (všimněte si použití poddotazu k hodnocení řádků):

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

Krok 3: vyberte pouze řádky, kde je pořadí menší než nějaké číslo:

select * 
from keyword_user_ranked 
where rank <= 3;

Příklad:

Použitá základní data:

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

Seskupeno podle klíčového slova a uživatele:

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

Uživatelé seřazení v rámci klíčových slov:

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

Pouze první 2 z každého klíčového slova:

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

Všimněte si, že když jsou nerozhodné výsledky – viz uživatelé 2 a 4 pro klíčové slovo „mysql“ v příkladech – všechny strany v nerozhodném výsledku získají „poslední“ pořadí, tj. pokud jsou 2. a 3. nerozhodné, oběma je přiřazena hodnost 3.

Výkon:pomůže přidání indexu do sloupců klíčových slov a uživatelů. Mám tabulku dotazovanou podobným způsobem se 4000 a 1300 odlišnými hodnotami pro dva sloupce (v tabulce o 600 000 řádcích). Index můžete přidat takto:

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

V mém případě čas dotazu klesl z přibližně 6 sekund na přibližně 2 sekundy.



  1. Výkonnostní překvapení a předpoklady:Libovolné TOP 1

  2. Obnovte kopii vaší databáze

  3. Kanonická funkce EntityFunctions.TruncateTime v MYSQL neexistuje

  4. Kdy byste měli používat SQL Server s Access? (Tip:Téměř vždy)