Pergunta

Estou testando a seguinte consulta:

SELECT A,B,C FROM table WHERE field LIKE 'query%'
UNION
SELECT A,B,C FROM table WHERE field LIKE '%query'
UNION
SELECT A,B,C FROM table WHERE field LIKE '%query%'
GROUP BY B ORDER BY B ASC LIMIT 5

São três perguntas juntas, mais ou menos.No entanto, o conjunto de resultados retornado reflete os resultados da consulta nº 3 antes dos resultados da consulta nº 1, o que é indesejado.

Existe alguma maneira de priorizá-los para que os resultados sejam todos para a consulta nº 1, depois todos para a consulta nº 2 e depois todos para a consulta nº 3?Não quero fazer isso em PHP ainda (sem falar em ter que controlar os resultados que apareceram na primeira consulta para não aparecerem na segunda e assim por diante).

Foi útil?

Solução

Talvez você devesse tentar incluir uma quarta coluna, informando a tabela de onde ela veio, e então ordenar e agrupar por ela:

SELECT A,B,C, "query 1" as origin FROM table WHERE field LIKE 'query%'
UNION
SELECT A,B,C, "query 2" as origin FROM table WHERE field LIKE '%query'
UNION
SELECT A,B,C, "query 3" as origin FROM table WHERE field LIKE '%query%'
GROUP BY origin, B ORDER BY origin, B ASC LIMIT 5

Outras dicas

Adicione uma coluna adicional com valores codificados que você usará para classificar o conjunto de resultados geral, assim:

SELECT A,B,C,1 as [order] FROM table WHERE field LIKE 'query%'
UNION
SELECT A,B,C,2 as [order] FROM table WHERE field LIKE '%query'
UNION
SELECT A,B,C,3 as [order] FROM table WHERE field LIKE '%query%'
GROUP BY B ORDER BY [order] ASC, B ASC LIMIT 5

Você pode fazer isso como uma subseleção, algo como

SELECT * FROM (
    SELECT A,B,C FROM table WHERE field LIKE 'query%'
    UNION
    SELECT A,B,C FROM table WHERE field LIKE '%query'
    UNION
    SELECT A,B,C FROM table WHERE field LIKE '%query%'
) ORDER BY B ASC LIMIT 5

Selecione distinto a, b, c de (selecione a, b, c, 1 como o da tabela onde campo como 'consulta%' união selecione a, b, c, 2 como o da tabela, onde o campo como '%consulta' união selecionar A, b, c, 3 como o da tabela onde o campo como '%consulta%') ordem por o limite asc 5

Seria a minha maneira de fazer isso.Eu não sei como isso escala.

Eu não entendo o

GROUP BY B ORDER BY B ASC LIMIT 5

Aplica-se apenas ao último SELECT da união?

O mysql realmente permite agrupar por uma coluna e ainda não agregar nas outras colunas?

EDITAR:aahh.Vejo que o mysql realmente faz.É uma versão especial do DISTINCT(b) ou algo assim.Eu não gostaria de tentar ser um especialista nessa área :)

Se não houver uma classificação que faça sentido ordená-los, não junte os resultados - apenas retorne três conjuntos de registros separados e lide com eles adequadamente em sua camada de dados.

Eventualmente (olhando todas as sugestões) cheguei a esta solução, é um meio-termo entre o que preciso e o tempo.

SELECT * FROM 
  (SELECT A, B, C, "1" FROM table WHERE B LIKE 'query%' LIMIT 3
   UNION
   SELECT A, B, C, "2" FROM table WHERE B LIKE '%query%' LIMIT 5)
AS RS
GROUP BY B
ORDER BY 1 DESC

entrega 5 resultados no total, classifica a partir da quarta "coluna" e me dá o que preciso;um conjunto de resultados naturais (está vindo do AJAX) e um conjunto de resultados curinga logo em seguida.

:)

/mp

Existem duas variantes de UNION.

'UNION' and 'UNION ALL'

Na maioria dos casos, o que você realmente quer dizer é UNION ALL, pois não elimina duplicatas (pense SELECT DISTINCT) entre conjuntos, o que pode resultar em uma grande economia em termos de tempo de execução.

Outros sugeriram vários conjuntos de resultados, o que é uma solução viável, no entanto, eu alertaria contra isso em aplicativos sensíveis ao tempo ou aplicativos conectados por WANs, pois isso pode resultar em significativamente mais viagens de ida e volta na rede entre o servidor e o cliente.

Não entendo porque a necessidade de união para retirar os dados de uma única tabela SELECT A ,B ,C FROM table WHERE field LIKE 'query%' or field LIKE '%query' or field LIKE '%query%' GROUP BY B ORDER BY B ASC LIMIT 5

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top