2009-10-05 21 views
6

De alguna manera necesito esta característica, pero MySQL no la admite en este momento.Cómo hackear MySQL GROUP_CONCAT para recuperar un número limitado de filas?

Estoy usando GROUP_CONCAT(CONCAT(...)) para generar un material similar a xml.

¡Pero cuando el tamaño excede el límite, el xml simplemente se rompe!

¡De modo que tengo que hacer que solo recupere 5 filas!

+0

aumento en el valor group_concat_max_len my.cnf – Omesh

+1

puede ser que usted puede obtener su respuesta aquí http://stackoverflow.com/questions/3378324/limit-ignored-in-query-with-group-concat http://stackoverflow.com/questions/23608464/group-concat-with-limit –

Respuesta

2

¿Usa una tabla/subconsulta temporal para limitar los resultados? Sin ver su consulta, será difícil dar un consejo sólido para esa ruta.

Sin embargo, puede encontrar que la configuración group_concat_max_len es más útil. Controla la longitud máxima de una operación GROUP_CONCAT, en longitud de cadena. Suba para evitar GROUP_CONCAT s roto, cuando no puede permitirse limitar los resultados.

2

No es realmente una respuesta a su pregunta, sino una referencia para otras personas que también se desea utilizar una cláusula LIMIT en GROUP_CONCAT():

Un feature-request fue presentada hace mucho tiempo para los desarrolladores de MySQL. Todavía no implementado :-(

4

Un ejemplo de Charles respuesta:

básica:

SELECT GROUP_CONCAT(field) FROM (SELECT field FROM table LIMIT 200) 

extendieron:

REPARTO puede ser útil si el resultado se truncan por buffer:

SELECT CAST(GROUP_CONCAT(field) AS CHAR(2048)) FROM (SELECT field FROM table LIMIT 200) 
+0

Sí, funcionará. Pero necesitará una construcción más compleja para una consulta con 'GROUP BY '. –

+0

Recibí un error de "Cada tabla derivada debe tener su propio alias" cuando se utiliza la primera consulta. Para solucionar esto, lo cambié a "SELECT GROUP_CONCAT (campo) FROM (SELECT campo FROM tabla LIMIT 200) con el alias de" Gracias por la respuesta. – Henry

15

He trabajado alrededor de esto usando SUBSTRING_INDEX.

Por ejemplo:

SELECT SUBSTRING_INDEX(GROUP_CONCAT(Field1 SEPARATOR ','), ',', [# of elements to return]) 
FROM Table1; 
+0

Devuelve blob, pero este funciona. –

0

Para aquellos casos donde no se puede utilizar una tabla temporal, La mejor forma que conozco es seleccionar un separador oscura y luego truncar a partir de la primera instancia de dicho carácter. Este ejemplo usa el carácter NUL.

select substring_index(group_concat(field separator '\0'), '\0', 5) from table;

Dónde field es el nombre del campo, 5 es el número de resultados.

El inconveniente es que si su primera fila contiene ese carácter, será un resultado parcial.

Una solución alternativa sería reemplazar '\0' con una cadena aleatoria más larga.

Es bueno saber que field podría reemplazarse para incluir más información usando concat.

Tenga en cuenta que group_concat_max_len tiene un valor predeterminado de 1024 caracteres, por lo que debe considerar cambiar eso globalmente o dentro de su aplicación si quiere más que eso.

0

puede simular el particionado row_number usando variables de usuario y luego limitar filas y aplicar GROUP_CONCAT:

Considere la siguiente tabla:

create table your_table (
    id int primary key autoincrement, 
    category int, 
    value int 
); 

y datos:

insert into your_table (category, value) 
values 
(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), 
(2, 6), (2, 7), (2, 8), (2, 9), (2, 10), 
(3, 11), (3, 12), (3, 13), (3, 14), (3, 15); 

y queremos es el valor superior 3 (en el orden de la última identificación) por categoría concatenada:

select category, 
    group_concat(value order by id desc) as value_con 
from (
    select t.*, 
     @rn := if(@category = category, @rn + 1, if(@category := category,1, 1)) as seqnum 
    from your_table t 
    cross join (select @category := null, @rn := 0) x 
    order by t.category, t.id desc 
    ) t 
where seqnum <= 3 
group by category; 

Salida:

category value_con 
1   5,4,3 
2   10,9,8 
3   15,14,13 

Aquí está una demo de este.

Cuestiones relacionadas