2010-09-24 10 views
7

Sto cercando di capire come ordinare articoli con tag corrispondenti per il numero di tag corrispondenti.Ordinamento di articoli con tag corrispondenti per numero di tag corrispondenti a

Diciamo che avere tre tabelle di MySQL:

  • tags(tag_id, title)
  • articles(article_id, some_text)
  • articles_tags(tag_id, article_id)

Ora diciamo che si hanno quattro articoli in cui:

article_id = 1 ha tag " umorismo "," f unny "e" esilarante ".

article_id = 2 ha tag "divertente", "silly," e "goofy."

article_id = 3 ha le etichette "divertente", "silly" e "goofy."

article_id = 4 ha il tag "del tutto sul serio."

È necessario trovare tutti gli articoli relativi a article_id = 2 di almeno un tag corrispondente e restituire i risultati in ordine delle migliori corrispondenze. In altre parole, il article_id = 3 dovrebbe venire prima, con article_id = 1 in secondo luogo e article_id = 4 non dovrebbe essere visualizzato affatto.

È questo qualcosa che è fattibile in query SQL o da soli, o si tratta di più adatto per una cosa del genere Sphinx? Se il primo, che tipo di query dovrebbe essere fatto, e che tipo di indici dovrebbero essere creati per i risultati più performanti? Se quest'ultimo, per favore, espandi.

risposta

10

provare qualcosa di simile:

select article_id, count(tag_id) as common_tag_count 
from articles_tags 
group by tag_id 
where tag_id in (
    select tag_id from articles_tags where article_id = 2 
) and article_id != 2 
order by common_tag_count desc; 

sintassi potrebbe essere necessario un piccolo ritocco per MySQL.

o questo che funziona realmente: ;-)

SELECT at1.article_id, Count(at1.tag_id) AS common_tag_count 
FROM articles_tags AS at1 INNER JOIN articles_tags AS at2 ON at1.tag_id = at2.tag_id 
WHERE at2.article_id = 2 
GROUP BY at1.article_id 
HAVING at1.article_id != 2 
ORDER BY Count(at1.tag_id) DESC; 
+0

la seconda sintassi è fantastico e ha funzionato esattamente il modo in cui avevo bisogno. Grazie mille! –

2

qualcosa di simile:

SELECT a.* 
FROM articles AS a 
INNER JOIN articles_tags AS at ON a.id=at.article_id 
INNER JOIN tags AS t ON at.tag_id = t.id 
WHERE t.title = 'funny' OR t.title = 'goofy' OR t.title = 'silly' AND a.id != <article_id> 
GROUP BY a.id 
ORDER BY COUNT(a.id) DESC 

Con solo i soliti indici, assumendo articles_tags ha PK (article_id, tag_id), ed un indice su tags.title

Problemi correlati