MySQL et GROUP_CONCAT () longueur maximale


260

J'utilise GROUP_CONCAT()dans une requête MySQL pour convertir plusieurs lignes en une seule chaîne. Cependant, la longueur maximale du résultat de cette fonction est de 1024caractères.

Je suis très conscient que je peux changer le paramètre group_concat_max_lenpour augmenter cette limite:

SET SESSION group_concat_max_len = 1000000;

Cependant, sur le serveur que j'utilise, je ne peux changer aucun paramètre. Pas en utilisant la requête précédente et en ne modifiant aucun fichier de configuration.

Ma question est donc la suivante: existe-t-il un autre moyen d'obtenir la sortie d'une requête à plusieurs lignes dans une seule chaîne?


1
Vous voulez dire autre chose que de faire le travail côté client?
lexu

40
Merci mon pote ... votre question est la réponse à ma question :)
Mansoorkhan Cherupuzha

Vous semblez avoir déjà choisi une réponse, mais par curiosité, pourquoi ne pouvez-vous pas utiliser l' SETinstruction pour modifier une variable de session?
Bill Karwin

2
C'est parce que la requête que je devais créer était intégrée dans un framework php maison pourri, et je n'étais pas autorisé à modifier toute autre partie. La façon dont ce projet a été codé était vraiment honteuse.
ZeWaren

1
je me demandais quand en utilisant la fonction group_concat ma chaîne était de retour break, je ne savais pas que cette fonction renvoyait un nombre limité de char merci mon pote votre question m'a clarifié :)
MasoodUrRehman

Réponses:


335
SET SESSION group_concat_max_len = 1000000;

est un paramètre temporaire de portée de session. Cela ne s'applique qu'à la session en cours. Vous devez l'utiliser comme ceci.

SET SESSION group_concat_max_len = 1000000;
select group_concat(column) from table group by column

Vous pouvez le faire même en partageant l'hébergement, mais lorsque vous utilisez une autre session, vous devez répéter la SET SESSIONcommande.


4
J'ai préféré utiliser GLOBAL au lieu de SESSION: SET GLOBAL group_concat_max_len=6999pour rendre le paramètre valide pour toutes les requêtes
IcedDante

2
Rackspace et autres serveurs cloud n'autorisent pas l'accès GLOBAL. J'essaie d'utiliser jdbc.execute ("SET SESSION group_concat_max_len = ..."); à l'intérieur de la méthode d'initialisation de Dao mais comme l'a indiqué keatkeat, ce n'est que temporaire. Si quelqu'un connaît la bonne façon d'effectuer ce changement de façon permanente
veuillez

61

Le paramètre correct pour définir la longueur maximale est:

SET @@group_concat_max_len = value_numeric;

value_numericdoit être> 1024; par défaut, la group_concat_max_lenvaleur est 1024.


3
SET SESSION et SET GLOBAL ne fonctionnaient pas sur un certain serveur, mais cela a fonctionné! Merci!
mfink

cela a fonctionné alors que les autres suggestions ne l'ont pas @ MySQL Server 5.1.41 (je sais que c'est une ancienne version)
low_rents

2
Vous pouvez en fait définir un niveau group_concat_max_lenaussi bas que 4 . ( documentation mysql ). " value_numericdoit être> = 4" est le cas ici. J'ai effectivement utilisé cela pour tester ce qui se passe lorsque vous dépassez la group_concat_max_lenvaleur.
Thomas F

1
Je peux confirmer que ce paramètre n'est absolument PAS anti-redémarrage: une fois mysql redémarré, la propriété est réinitialisée à 1024, donc -1 pour moi
Frédéric

2
@NoWay vous devez définir la valeur dans un fichier de configuration (par exemple my.cnf) pour que le paramètre s'applique au redémarrage de mysql. Aucune SETrequête n'affectera les paramètres après un redémarrage.
Buttle Butkus

18

Incluez ce paramètre dans le fichier de configuration xampp my.ini:

[mysqld]
group_concat_max_len = 1000000

Redémarrez ensuite xampp mysql


8

Vous pouvez essayer ceci

SET GLOBAL group_concat_max_len = 1000000;

J'utilise ce client sqlyog pour ma base de données, mais il ne se reflète pas. Mais cela semble fonctionner lorsque je l'exécute via mon programme java
Jerry

5

La syntaxe correcte est mysql> SET @@global.group_concat_max_len = integer;
Si vous n'avez pas les privilèges pour le faire sur le serveur où réside votre base de données, utilisez une requête comme:
mySQL = "SET @@session.group_concat_max_len = 10000;"ou une valeur différente.
Ligne suivante:
SET objRS = objConn.Execute(mySQL)  vos variables peuvent être différentes.
puis
mySQL="SELECT GROUP_CONCAT(......);"etc
j'utilise la dernière version car je n'ai pas les privilèges pour changer la valeur par défaut de 1024 globalement (en utilisant cPanel).
J'espère que cela t'aides.


2
CREATE TABLE some_table (
  field1 int(11) NOT NULL AUTO_INCREMENT,
  field2 varchar(10) NOT NULL,
  field3 varchar(10) NOT NULL,
  PRIMARY KEY (`field1`)
);

INSERT INTO `some_table` (field1, field2, field3) VALUES
(1, 'text one', 'foo'),
(2, 'text two', 'bar'),
(3, 'text three', 'data'),
(4, 'text four', 'magic');

Cette requête est un peu étrange mais elle n'a pas besoin d'une autre requête pour initialiser la variable; et il peut être intégré dans une requête plus complexe. Il retourne tous les «champs2 séparés par un point-virgule.

SELECT result
FROM   (SELECT @result := '',
               (SELECT result
                FROM   (SELECT @result := CONCAT_WS(';', @result, field2) AS result,
                               LENGTH(@result)                            AS blength
                        FROM   some_table
                        ORDER  BY blength DESC
                        LIMIT  1) AS sub1) AS result) AS sub2; 

1
C'est une excellente réponse, mais ne termine pas tout à fait la question - voici comment obtenir un très long concat, mais qu'en est-il du regroupement? Votre requête ne renvoie qu'une seule ligne, au lieu d'une ligne par groupe.
Benubird

Je me souviens que c'est ce que j'essayais de faire - rassembler l'ensemble des résultats en une seule chaîne.
ZeWaren

9
@Benubird c'est une très mauvaise requête. et par mauvais je veux dire terrible. l'OP effectue une sous-requête corrélée qui a une sous-requête qui est à l'intérieur d'une sous-requête. si vous deviez examiner que par des comparaisons de données, vous auriez 256 comparaisons sur son échantillon de données aka 4 lignes .. imaginez maintenant si vous avez 1k lignes c'est 1 billion de comparaisons.
John Ruddell

@JohnRuddell Oui, ça l'est. Je peux vous assurer que cette requête est loin d'être à l'intérieur d'un système live sérieux. À l'époque, j'en avais besoin pour une sorte de défi / exercice.
ZeWaren

5
Ah gotcha .. Je vous recommanderais de le noter pour les autres passants ... Comme cette réponse sera trompeuse :) tentative intéressante cependant
John Ruddell
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.