2015-07-30 1 views
0

Je dois faire correspondre une entrée d'utilisateur avec une colonne de chaîne. Les deux contiennent des mots séparés par des espaces.SQL: correspondance d'un ensemble de mots par rapport à un autre ensemble et tri par nombre et par préfixe des correspondances

Les critères de classement est: nombre

  1. des mots qui correspondent depuis le début (match de préfixe) desc
  2. nombre de mots qui correspondent colonnes desc
  3. où les mots assortis viennent dans le même ordre comme dans la phrase d'entrée viennent en premier

Donc, étant donné l'échantillon suivant d ata

"one sample" 
"un moment" 
"no match" 
"sample uno" 
"uno sample" 
"sample oun" 

et l'entrée de l'échantillon "sa un foo", la sortie doit être:

  1. "sample uno" - 2 correspondances préfixe
  2. "uno sample" - même, mais l'ordre des mots diffère
  3. "sample oun" - 1 préfixe match + 2 mots appariés
  4. "un moment", "one sample" - 1 préfixe match

La question est: puis-je implémenter ceci dans une seule requête SQL (postgresql)? Je suis assez inexpérimenté avec SQL, donc j'apprécie toute aide. Merci!

I comprennent simple SQL FIDDLE

+0

Pour votre échantillon quelles informations ajoutent «foo» à l'entrée de l'échantillon? –

+0

Il impose le message "tous les mots ne doivent pas être appariés" – meandre

+0

Désolé encore, ne pas undestand, si je supprime 'foo' des données d'entrée, le résultat serait différent? –

Répondre

1
  • premier ASIGN et id à chaque ligne
  • divisé chaque donnée par space
  • entrée divisée par space
  • croix joindre les deux tables et vérifier si l'entrée apparaissent sur Les données.
  • dernière rejoindre la table d'origine et compter combien de préfixe et contiennent ont.

Il y a un cas, je pense que peut exiger atention spéciale si l'on mots d'entrée apparaissent comme préfixe et deuxième mot apparaissent comme contiennent du même mot

données: FORMAT
entrée : FO AT

SQL FIDDLE DEMO

WITH data as (
    SELECT 
     row_number() OVER (ORDER BY field) AS id, 
     field 
    FROM 
     dtable 
), 
data_split as (
    SELECT 
     id, 
     unnest(string_to_array(field, ' ')) AS elem 
    FROM data 
), 
input_split as (
    SELECT 
     unnest(string_to_array(field, ' ')) AS elem 
    FROM input 
), 
match as (
    SELECT *, strpos(d.elem, i.elem) as match_pos 
    FROM input_split i, data_split d 
) 
select 
    match.id, 
    data.field, 
    SUM(CASE WHEN match_pos = 1 THEN 1 ELSE 0 END) prefix, 
    SUM(CASE WHEN match_pos > 1 THEN 1 ELSE 0 END) contain 
from 
    match inner join 
    data on match.id = data.id 
group by match.id, data.field 
order by 3 desc, 4 desc 

+0

Le résultat de la requête est erroné – meandre

+0

pouvez-vous expliquer pourquoi est faux? –

+0

peut-être qu'il diffère de l'exemple? – meandre