Die SELECT-Liste befindet sich nicht in der GROUP BY-Klausel und enthält eine nicht aggregierte Spalte, die nicht mit sql_mode = only_full_group_by kompatibel ist

107

Ich verwende MySQL 5.7.13 auf meinem Windows-PC mit WAMP Server

Hier ist mein Problem beim Ausführen dieser Abfrage

SELECT *
FROM `tbl_customer_pod_uploads`
WHERE `load_id` = '78' AND
      `status` = 'Active'
GROUP BY `proof_type`

Ich bekomme immer Fehler wie diesen

Ausdruck Nr. 1 der SELECT-Liste befindet sich nicht in der GROUP BY-Klausel und enthält die nicht aggregierte Spalte 'returntr_prod.tbl_customer_pod_uploads.id', die funktional nicht von den Spalten in der GROUP BY-Klausel abhängig ist. Dies ist nicht kompatibel mit sql_mode = only_full_group_by

Können Sie mir bitte die beste Lösung nennen ...

Ich brauche Ergebnis wie

+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
| id | user_id | load_id | bill_id | latitude | langitude | proof_type | document_type | file_name    | is_private | status | createdon           | updatedon           |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
|  1 |       1 | 78      | 1       | 21.1212  | 21.5454   |          1 |             1 | id_Card.docx |          0 | Active | 2017-01-27 11:30:11 | 2017-01-27 11:30:14 |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
Dhanu K.
quelle
12
Nicht benutzen SELECT *.
Shmosel
sagen wie tbl_customer_pod_uploadsload_idstatusproof_type
folgt
2
Wenn Sie Kompatibilität für alte Abfragen wünschen, können Sie den only_full_group_bySQL-Modus deaktivieren.
Barmar
4
Versuchen Sie es mit ANY_VALUE (Proof_Type): dev.mysql.com/doc/refman/5.7/de/group-by-handling.html SELECT *, ANY_VALUE (Proof_Type) FROM tbl_customer_pod_uploadsWHERE load_id= '78' AND status= 'Active' GROUP BYproof_type
AlexGach

Antworten:

220

Dies

Ausdruck Nr. 1 der SELECT-Liste befindet sich nicht in der GROUP BY-Klausel und enthält die nicht aggregierte Spalte 'returntr_prod.tbl_customer_pod_uploads.id', die funktional nicht von den Spalten in der GROUP BY-Klausel abhängig ist. Dies ist nicht kompatibel mit sql_mode = only_full_group_by

wird einfach gelöst, indem der SQL-Modus in MySQL mit diesem Befehl geändert wird.

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

Das funktioniert auch für mich. Ich habe dies verwendet, weil es in meinem Projekt viele Abfragen wie diese gibt, also habe ich diesen SQL-Modus einfach in only_full_group_by geändert

Danke... :-)

Dhanu K.
quelle
13
Für mich geht das!. Du rettest meinen Tag. Denken Sie daran, MYSQL SERVICE neu zu starten
marcode_ely
2
Wenn ich Codeigniter verwende und im Modell ausführen möchte, wie würde ich es dann verwenden? Kann mir helfen ? @marcode_ely
DhavalThakor
@DhavalThakor: Sobald Sie diese Abfrage auf Ihrem Server ausgeführt haben, müssen Sie sie nicht mehr immer wieder ausführen. Sie müssen es also nicht in Ihr Modell
einfügen
2
MySQL 5.7.29 musste den Dienst nicht neu starten
Taavi
68

Wenn der MySQL- only_full_group_byModus aktiviert ist, gelten bei der Verwendung strenge ANSI-SQL-Regeln GROUP BY. In Bezug auf Ihre Abfrage bedeutet dies, dass Sie, wenn Sie GROUP BYvon der proof_typeSpalte sind, nur zwei Dinge auswählen können:

  • die proof_typeSpalte oder
  • Aggregate einer anderen Spalte


Mit „Aggregaten“ von anderen Spalten, meine ich mit einer Aggregatfunktion wie MIN(), MAX()oder AVG()mit einer anderen Spalte. In Ihrem Fall wäre also die folgende Abfrage gültig:

SELECT proof_type,
       MAX(id) AS max_id,
       MAX(some_col),
       MIN(some_other_col)
FROM tbl_customer_pod_uploads
WHERE load_id = '78' AND
      status = 'Active'
GROUP BY proof_type

Bei der überwiegenden Mehrheit der MySQL- GROUP BYFragen, die ich in SO sehe, ist der strikte Modus deaktiviert, sodass die Abfrage ausgeführt wird, jedoch mit falschen Ergebnissen. In Ihrem Fall wird die Abfrage überhaupt nicht ausgeführt, sodass Sie überlegen müssen, was Sie wirklich tun möchten.

Hinweis: Das ANSI-SQL erweitert das, was ausgewählt werden darf, um GROUP BYauch Spalten, die funktional von den ausgewählten Spalten abhängen . Ein Beispiel für eine funktionale Abhängigkeit wäre die Gruppierung nach einer Primärschlüsselspalte in einer Tabelle. Da der Primärschlüssel garantiert für jeden Datensatz eindeutig ist, wird auch der Wert einer anderen Spalte bestimmt. MySQL ist eine der Datenbanken, die dies zulässt (SQL Server und Oracle AFAIK nicht).

Tim Biegeleisen
quelle
2
Nur eine Anmerkung: Das Ergebnis ist nicht falsch (es folgt den MySQL-Regeln), aber es ist unvorhersehbar. Das bedeutet, dass Spalten, die nicht Teil der Gruppe sind und nicht aggregiert (und nicht funktionsabhängig), einen 'zufälligen' Wert von der entsprechenden Gruppe zurückgeben. Wie im Handbuch angegeben: "Der Server kann aus jeder Gruppe einen beliebigen Wert auswählen"
Pred
Ein Verstoß gegen die strikte Gruppierung führt nicht unbedingt zu falschen Ergebnissen. Normalerweise mache ich das, wenn die Felder garantiert identisch sind (z. B. ein Eins-zu-Viele-Join). Und selbst wenn dies nicht garantiert ist, ist die Auswahl einer beliebigen Zeile oft nicht mehr falsch als die Verwendung einer Aggregatfunktion oder das Hinzufügen einer Gruppierungsebene.
Shmosel
38

Verwenden Sie eine beliebige Lösung

(1) PHPMyAdmin

Wenn Sie phpMyAdmin verwenden, ändern Sie die Einstellung " sql_mode " wie im folgenden Screenshot beschrieben. Geben Sie hier die Bildbeschreibung ein

Bearbeiten Sie die Variable "SQL-Modus" und entfernen Sie den Text "ONLY_FULL_GROUP_BY" aus dem Wert

(2) SQL / Eingabeaufforderung Führen Sie den folgenden Befehl aus.

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

(3) Verwenden Sie SELECT * nicht

Verwenden Sie die entsprechende Spalte in der SELECT-Abfrage. Relevant bedeutet Spalten, die entweder in der Klausel "Gruppieren nach" oder in der Spalte mit der Aggregatfunktion (MAX, MIN, SUMME, COUNT usw.) enthalten sind.


Wichtige Notiz

Änderungen, die mit Punkt (1) ODER Punkt (2) vorgenommen wurden, setzen ihn nicht DAUERHAFT und werden nach jedem Neustart zurückgesetzt.

Sie sollten dies also in Ihrer Konfigurationsdatei festlegen (z. B. /etc/mysql/my.cnf im Abschnitt [mysqld]), damit die Änderungen nach dem Neustart von MySQL wirksam bleiben:

Config File : /etc/mysql/my.cnf

Variablenname : sql_mode ODER sql-mode

Rakesh Soni
quelle
17

Sie können sql_mode = only_full_group_by mit einem Befehl deaktivieren. Sie können dies über das Terminal oder die MySql-IDE versuchen

mysql> set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

mysql> set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
Anil Gupta
quelle
16

Die folgende Methode hat mein Problem gelöst:

In Ubuntu

Art: sudo vi /etc/mysql/my.cnf

Geben Sie A ein, um den Einfügemodus aufzurufen

In der letzten Zeile unter zwei Zeilen Code einfügen:

[mysqld]
sql_mode = STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION

Geben Sie esc ein, um den Eingabemodus zu verlassen

Type :wq to save and close vim.

Geben Sie ein sudo service mysql restart, um MySQL neu zu starten.

Anand Huded
quelle
danke, es hat funktioniert! in cent os, whm, my.cnf befand sich am
Reejesh PK
9

Damit die Abfrage in SQL92 zulässig ist, muss die Namensspalte in der Auswahlliste weggelassen oder in der GROUP BY-Klausel benannt werden.

SQL99 und höher erlaubt solche Nichtaggregate pro optionalem Feature T301, wenn sie funktional von GROUP BY-Spalten abhängig sind: Wenn eine solche Beziehung zwischen name und custid besteht, ist die Abfrage zulässig. Dies wäre beispielsweise der Fall, wenn ein Primärschlüssel der Kunden verwahrt würde.

MySQL 5.7.5 und höher implementiert die Erkennung der funktionalen Abhängigkeit. Wenn der SQL-Modus ONLY_FULL_GROUP_BY aktiviert ist (dies ist standardmäßig der Fall), lehnt MySQL Abfragen ab, für die die Auswahlliste, die HAVING-Bedingung oder die ORDER BY-Liste auf nicht aggregierte Spalten verweisen, die weder in der GROUP BY-Klausel benannt noch funktional von ihnen abhängig sind .

via MySQL :: MySQL 5.7 Referenzhandbuch :: 12.19.3 MySQL-Behandlung von GROUP BY

Sie können es lösen, indem Sie den SQL-Modus mit diesem Befehl ändern:

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));

und ... denken Sie daran, die Datenbank wieder zu verbinden !!!

ElliotMok
quelle
8

In Ubuntu

Schritt 1:

sudo vi /etc/mysql/mysql.conf.d/mysqld.cnf

Schritt 2: Gehen Sie zur letzten Zeile und fügen Sie Folgendes hinzu

sql_mode = ""

Schritt 3: Speichern

Schritt 4: Starten Sie den MySQL-Server neu.

Gullu Mutullu
quelle
5

Gehen Sie zu phpmyadmin, öffnen Sie die Konsole und führen Sie diese Anforderung aus

SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY',''));
fajr abd el ali
quelle
3

Suchen Sie nach "SQL-Modus", wenn Sie PhpMyAdmin verwenden, und entfernen Sie den Wert : ONLY_FULL_GROUP_BY, habe es gerade getan und es ist in Ordnung.

Mr_Bull
quelle
2

Wie es aussieht, wird die Gruppierung nach mehreren Spalten / Feldern Ihrem Ergebnis nicht schaden. Warum versuchen Sie nicht, der Gruppe Folgendes hinzuzufügen:

GROUP BY `proof_type`, `id`

Dies wird durch Gruppe proof_typezuerst , dann id. Ich hoffe, dass dies die Ergebnisse nicht verändert. In einigen / den meisten Fällen führt die Gruppierung nach mehreren Spalten zu falschen Ergebnissen.

jkkenzie
quelle
2
> sudo nano /etc/mysql/my.cnf

Geben Sie unten ein

[mysqld]
sql_mode = ""

Strg + O => Y = Strg + X.

> sudo service mysql restart
Sundar
quelle
1
  1. Melden Sie sich bei phpMyAdmin an
  2. Navigieren Sie zu: Server: localhost: 3306 und wählen Sie keine Datenbank aus
  3. Klicken Sie im oberen Menü auf Variablen
  4. Suchen Sie nach "SQL-Modus" und bearbeiten Sie den entsprechenden Wert in: NO_ENGINE_SUBSTITUTION

Das ist alles.

Ich habe das in meinem Ec2 gemacht und es hat wie ein Zauber funktioniert.

PrafulPravin
quelle
1

Hier ist eine sehr schnelle und einfache Möglichkeit, es dauerhaft einzustellen

NB: Die Ausführung SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); ist vorübergehend und beim Neustart des Servers tritt immer noch der Fehler auf. Um dies dauerhaft zu beheben, gehen Sie wie folgt vor

  1. Melden Sie sich als root bei Ihrem Server an
  2. in Ihrem Terminal laufen wget https://gist.githubusercontent.com/nfourtythree/90fb8ef5eeafdf478f522720314c60bd/raw/disable-strict-mode.sh
  3. Machen Sie das Skript ausführbar, indem Sie es ausführen chmod +x disable-strict-mode.sh
  4. Führen Sie das Skript durch Ausführen aus ./disable-strict-mode.sh

Und wenn Sie fertig sind, werden Änderungen an MySQL vorgenommen und es wird neu gestartet

Nelson Bwogora
quelle
1

Hallo, anstatt alle Spalten zu nehmen, nimm einfach das, was du brauchst ANY_VALUE(column_name). Es funktioniert perfekt. Überprüfen Sie einfach.

Z.B:

SELECT proof_type,any_value("customer_name") as customer_name
FROM `tbl_customer_pod_uploads`
WHERE `load_id` = '78' AND `status` = 'Active' GROUP BY `proof_type`
siva.picky
quelle
0

Update für MySQL 8.0

Ihr sql-modewird nicht haben, NO_AUTO_CREATE_USERda es wie hier erwähnt entfernt wurde - wie man den SQL-Modus in meinem CNF in MySQL-8 einstellt

[mysqld]
sql-mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION"

Auch wenn jemand keine my.cnfDatei hat, erstellt er eine neue /etc/my.cnfund fügt dann die obigen Zeilen hinzu.

Gautam
quelle
-1

Öffnen Sie das WAMP-Panel und öffnen Sie die MySQL-Konfigurationsdatei. Suchen Sie darin nach "sql_mode", wenn Sie es finden, und setzen Sie es auf "". Wenn Sie es nicht finden, fügen Sie der Datei sql_mode = "" hinzu.

Starten Sie den MySQL-Server neu und Sie können loslegen ...

fröhliche Codierung.

Mohd Samgan Khan
quelle
-2

my.iniSchreiben Sie in Ihre :

[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION"

hängen von Ihrer Version ab. Oder:

[mysqld]
sql_mode = ""

oder einfach entfernen: ONLY_FULL_GROUP_BY

Gary Carranza Sebastian
quelle