Uma maneira (de muitas) de fazer isso:Remova o resto da string começando na correspondência e meça o comprimento da string truncada:
SELECT id, title
FROM book
WHERE title ILIKE '%deep%space%'
ORDER BY length(regexp_replace(title, 'deep.*space.*', '','i'));
Usando
ILIKE
na cláusula WHERE, já que normalmente é mais rápido (e faz o mesmo aqui).Observe também o quarto parâmetro para o
regexp_replace()
função ('i'
), para torná-lo insensível a maiúsculas e minúsculas. Alternativas
Conforme solicitação no comentário.
Ao mesmo tempo, demonstrando como classificar correspondências primeiro (e
NULLS LAST
). SELECT id, title
,substring(title FROM '(?i)(^.*)deep.*space.*') AS sub1
,length(substring(title FROM '(?i)(^.*)deep.*space.*')) AS pos1
,substring(title FROM '(?i)^.*(?=deep.*space.*)') AS sub2
,length(substring(title FROM '(?i)^.*(?=deep.*space.*)')) AS pos2
,substring(title FROM '(?i)^.*(deep.*space.*)') AS sub3
,position((substring(title FROM '(?i)^.*(deep.*space.*)')) IN title) AS p3
,regexp_replace(title, 'deep.*space.*', '','i') AS reg4
,length(regexp_replace(title, 'deep.*space.*', '','i')) AS pos4
FROM book
ORDER BY title ILIKE '%deep%space%' DESC NULLS LAST
,length(regexp_replace(title, 'deep.*space.*', '','i'));
Você pode encontrar a documentação para todos os itens acima no manual aqui e aqui .
-> SQLfiddle demonstrando tudo.