2017-03-28 2 views
1

J'essaie d'utiliser MySQL pour afficher les métadonnées. Mon objectif est de voir la table qui a le plus grand nombre d'attributs. J'ai une table (appelons-la T) qui contient les colonnes table_name et num_att (nombre d'attributs).MySQL saute sans clause GROUP BY

Lorsque je tente d'exécuter SElECT table_name, MAX(num_att) FROM T; erreurs sur moi que je dois avoir une instruction GROUP BY lorsque sql_mode=only_full_group_by qui a été activée par défaut dans l'installation. Donc, j'ai désactivé only_full_group_by en exécutant SET sql_mode='';. Cela m'a permis d'exécuter la requête ci-dessus sans utiliser l'instruction group by. Mais alors, quand j'exécute la requête ci-dessus, elle renvoie les mauvaises données - elle renvoie la bonne valeur MAX (num_att) mais combinée avec la mauvaise valeur nom_table (elle lie la valeur MAX (num_att) avec le premier nom_table valeur).

par exemple.

SELECT table_name, num_att FROM T;

sorties:

+------------+---------+ 
| table_name | num_att | 
+------------+---------+ 
| customer | 5  | 
| menuitem | 3  | 
| orderdetail| 4  | 
| orders  | 7  | 
| restaurant | 4  | 
+------------+---------+ 

Puis, quand je lance la requête globale SElECT table_name, MAX(num_att) FROM T;, je reçois ce

+------------+---------+ 
| table_name | num_att | 
+------------+---------+ 
| customer | 7  | 
+------------+---------+ 

quand il devrait être cette

+------------+---------+ 
| table_name | num_att | 
+------------+---------+ 
| orders  | 7  | 
+------------+---------+ 

Est-ce que quelqu'un sait pourquoi cela se passe? J'utilise MySQL version 5.7.14 sur Windows 10 WAMP sans avoir modifié les paramètres autres que le mot de passe et le sql_mode (comme mentionné ci-dessus).

Pour référence, T est la suivante:

SELECT table_name,count(column_name) AS num_att 
FROM (
    SELECT table_name,column_name,column_type 
    FROM information_schema.columns AS c 
     JOIN (
      SELECT table_schema, table_name 
      FROM information_schema.tables 
      WHERE table_schema='cr' 
     ) AS t 
    USING (table_name); 
) AS x 
GROUP BY table_name; 

où cr est le nom de ma base de données.

+0

Fonctionne comme prévu. MySQL est l'un des rares (seulement?) SGBDR qui autorise même une requête qui ne se regroupe pas avec toutes les colonnes non agrégées. Les valeurs des colonnes non groupées et non agrégées sont (effectivement choisies au hasard) parmi les valeurs rencontrées pour les colonnes groupées. (Pour montrer pourquoi il ne peut pas fonctionner comme vous le vouliez, quelle valeur attendez-vous de 'table_name' de' SELECT nom_table, MIN (num_att), MAX (num_att) FROM T; '?) – Uueerdo

+0

Ce n'est pas le seul système qui permet des fonctions agrégées sans groupe par. Je ne l'ai pas mentionné auparavant, mais SQLite3 renvoie les valeurs correctes pour les attributs non agrégés chaque fois que j'appelle MAX ou MIN. Je suppose que c'est pourquoi j'ai été si choqué que MySQL n'a pas renvoyé les combinaisons d'attributs correctes. – yuyu5

+0

Comment SQLite3 peut-il retourner des valeurs "correctes" pour des champs non agrégés?Par exemple, quelle est la valeur de 'f2' dans une requête telle que' SELECT f1, f2, MIN (f3), MAX (f3) FROM t1 GROUP BY f1'? – Uueerdo

Répondre

1

Si vous avez besoin d'un résultat de la fonction d'agrégation et la valeur de cette agrégation, vous ne pouvez pas effectuer cette requête avoinding le groupe par vous devez donc utiliser une sous-requête (ou une jointure), par exemple:

SELECT table_name, num_att 
FROM T 
where num_att = (select max(num_att) from T) 

cette fonctionnalité à partir de MySQL 5.7 .. version précédente permet également l'utilisation de la fonction aggreagated sans groupe par ... mais la colonne d'utilisation dans le groupe par est correctement ..

0

Vous pouvez utiliser le SUBSTRING_INDEX avec astuce GROUP_CONCAT

SELECT SUBSTRING_INDEX(GROUP_CONCAT(table_name ORDER BY num_att DESC),',',1), MAX(num_att) FROM T