[RAILS] Ein Fehler ist aufgetreten, weil die only_full_group_by von sql_mode nicht beobachtet wurde.

Problem

スクリーンショット 2020-11-04 午後1.44.09.png

Als ich versuchte, das Diagramm anzuzeigen, wurde der folgende Fehler angezeigt.

Mysql2::Error: Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'pfc-master_production.posts.created_at' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by: SELECT `posts`.`created_at` FROM `posts` WHERE `posts`.`user_id` = 8 GROUP BY date(created_at)

charts_controller.rb


@dates = dates_calorie.map { |dates| dates.created_at }

Lesen Sie das Fehlerprotokoll

Mysql2::Error: Expression #1 of SELECT list is not in GROUP BY clause and 
Mysql2 ::Fehler: Ausdruck Nr. 1 in der SELECT-Liste befindet sich nicht in der GROUP BY-Klausel

contains nonaggregated column 'pfc-master_production.posts.created_at' 
which is not functionally dependent on columns in GROUP BY clause;
Nicht aggregierte Spalten, die funktional nicht von den Spalten in der GROUP BY-Klausel abhängig sind
'pfc-master_production.posts.created_at'enthalten

this is incompatible with sql_mode=only_full_group_by: 
Das ist SQL_mode = only_full_group_Nicht kompatibel mit von

SELECT SUM(`posts`.`calorie`) AS sum_calorie, date(created_at) AS date_created_at FROM `posts` WHERE `posts`.`user_id` = 8 GROUP BY date(created_at) ORDER BY created_at DESC

** Was ist die Kartenmethode? ** ** **

・ Mit einem Wort ist die Zuordnungsmethode "eine Methode, die die Verarbeitung für jedes Element in der angegebenen Reihenfolge ausführt".

Array-Variable.map {|Variablennamen|Spezifische Verarbeitung}

In diesem Fall
@dates = dates_calorie.map(Array-Variable) { |dates(Variablennamen)| dates.created_at(wird bearbeitet) }

** Was ist im Array "Dates_Calorie"? ** ** **

dates_calorie = current_user.posts.group("date(created_at)").select(:created_at)

Wenn der angemeldete Benutzer an einem Tag mehrere Beiträge hat, werden diejenigen eingeschlossen, die nach Tag gruppiert sind und die Spalte "created_at" erhalten. Das heißt, pro Tag wird eine Spalte "created_at" erfasst, und die Spalteninformationen "created_at" für jeden Tag sind im Array enthalten.

Der Grund für das Abrufen dieser Informationen besteht darin, ein Diagramm zu implementieren, das das tägliche Gewicht zeigt. Dies liegt daran, dass ich bei mehreren Posts pro Tag nur einen pro Tag in der Grafik anzeigen möchte.

✖️ [2020-11-09 00:00:00, 2020-11-09 00:11:00, 2020-11-10 00:12:00] ○ [2020-11-09 00:00:00, 2020-11-10 00:12:00, 2020-11-11 00:12:00]

** Welche Art der Verarbeitung verwenden Sie mit der Kartenmethode? ** ** **

@dates = dates_calorie.map(Array-Variable) { |dates(Variablennamen)| dates.created_at(wird bearbeitet) }

Wie oben erläutert, enthält das Array date_calorie tägliche created_ats im Array. Mit der Map-Methode können Sie jedes Element im Array in eine Variable namens Datumsangaben einfügen. Nehmen Sie es heraus und erhalten Sie created_at.

Sie werden Instanzvariablen zugewiesen, um sie an chart.js zu übergeben, das das Diagramm mit gon anzeigt, und sie im Diagramm zu verwenden.

Warum hast du diesmal einen Fehler bekommen?

Ich kannte only_full_group_by nicht, also habe ich only_full_group_by in der Referenz nachgeschlagen.

** Was ist sql_mode = only_full_group_by? ** ** **

Lehnt Abfragen ab, auf die durch Auswahllisten, HAVING-Bedingungen oder (seit MySQL 5.6.5) ORDER-Listen für nicht aggregierte Spalten verwiesen wird, die in der GROUP BY-Klausel nicht benannt sind.

Wenn> ONLY_FULL_GROUP_BY aktiviert ist, ist die folgende Abfrage ungültig. Das erste ist, dass die nicht aggregierte Adressspalte in der Auswahlliste in der GROUP BY-Klausel nicht benannt ist, und das zweite ist ungültig, da max_age in der HAVING-Klausel in der GROUP BY-Klausel nicht benannt ist. Werden.

Was ist die MySQL-Referenz ONLY_FULL_GROUP_BY?

sql_mode entspricht den offiziellen Regeln von MySQL, und only_full_group_by scheint eine Regel zu sein, die in MySQL 5.6.5 oder höher neu festgelegt wurde.

-Es ist wahrscheinlich, dass ein Fehler aufgetreten ist, weil die Regel von only_full_group_by nicht befolgt wurde. -Es ist wahrscheinlich, dass ein Fehler aufgetreten ist, weil der Name nicht in der GROUP BY-Klausel angegeben wurde.

** Was ist die GROUP BY-Klausel? ** ** **

select [Elementname, der angezeigt werden soll] from [Tabellenname] GROUP BY [Elementname zur Gruppe];
SELECT team, COUNT(team) FROM user GROUP BY team;

Gegenmaßnahmen

Aus dem oben Gesagten ergeben sich zwei mögliche Gegenmaßnahmen.

(1) Wechseln Sie zu einem Code, der die GROUP BY-Klausel verwendet, um im SQL-Modus nur_full_group_by zu erfüllen. (2) Ändern Sie my.cnf (MySQL-Einstellungsdatei) und entfernen Sie die Einschränkung von only_full_group_by.

Dieses Mal habe ich Methode (2) gewählt. Der Grund ist, dass ich keine Zeit habe.

Jetzt, da ich anfange, den Job zu einem Webingenieur zu wechseln, muss ich in der Lage sein, die App so schnell wie möglich dem Personalchef des Unternehmens zu zeigen. Eigentlich ist ① wünschenswert, aber dieses Mal habe ich ② gewählt, weil die Zeit priorisiert ist.

Diese Lösung

my.Finden Sie den Ort von conf
[naota@ip-10-0-0-32 ~]$ mysql --help | grep my.cnf
                      order of preference, my.cnf, $MYSQL_TCP_PORT,
/etc/my.cnf /etc/mysql/my.cnf /usr/etc/my.cnf ~/.my.cnf 

my.Öffnen Sie conf
[naota@ip-10-0-0-32 ~]$ vi /etc/my.cnf

Wird beim Überschreiben einer schreibgeschützten Datei verwendet
:w !sudo tee %

Die folgende Beschreibung wurde zu "my.conf" hinzugefügt.

my.conf


[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

Ich habe mir sql_modes wie "NO_ZERO_IN_DATE" und "NO_ZERO_DATE" angesehen und festgestellt, dass es keinen Sinn macht, "only_full_group_by" alleine auszuschalten. Wahrscheinlich ist es nicht auf OFF gesetzt, weil es in der obigen Einstellung auf "only_full_group_by" gesetzt wurde, aber es wird nicht gesetzt, weil es nicht geschrieben wurde, einschließlich "only_full_group_by".

only_full_group_by Diese Hypothese war korrekt, da der Fehler am Anfang beim Hinzufügen aufgetreten ist.

Ich habe MySQL neu gestartet, damit die oben genannten Einstellungen wirksam werden.

Nach dem Update auf MySQL 5.7 ist ein Fehler mit only_full_group_by aufgetreten.

Stoppen Sie MySQL
[naota@ip-10-0-0-32 ~]$ sudo systemctl stop mysqld.service

Starten Sie MySQL
[naota@ip-10-0-0-32 ~]$ sudo systemctl start mysqld.service

Die Grafik wird angezeigt! スクリーンショット 2020-11-04 午後1.45.51.png

Quellcode

chart_controller.rb ist ein Controller zum Anzeigen von Grafiken.

charts_controller.rb


def index
    #Kalorie
    @sampleuser = User.find_by(id: 3)
    if user_signed_in?
      #Berechnen Sie die Gesamtkalorien nach Datum
      sum_calorie = current_user.posts.group("date(created_at)").sum(:calorie)
      #Da die Gesamtkalorien für jedes Datum in Form eines Hash vorliegen, rufen Sie den Wert ab, fügen Sie ihn in ein Array ein und weisen Sie ihn einer Variablen zu
      array_calorie = sum_calorie.values
    else
      sum_calorie = @sampleuser.posts.group("date(created_at)").sum(:calorie)
      array_calorie = sum_calorie.values
    end
    #Übergeben Sie Daten mit gon an js Seite
    gon.data = []
    #Extrahieren Sie die Gesamtkalorien für jedes Datum einzeln mit der Kartenmethode
    #Verwendung der Kartenmethode → Array-Variable.map {|Variablennamen|Spezifische Verarbeitung}
    gon.data = array_calorie.map { |calorie| calorie }

    if user_signed_in?
      #Erstellt nach Datum_Holen Sie sich nur an der Spalte. In Form eines Arrays gespeichert
      dates_calorie = current_user.posts.group("date(created_at)").select(:created_at)
    else
      dates_calorie = @sampleuser.posts.group("date(created_at)").select(:created_at)
    end

    gon.date = []
    @dates = dates_calorie.map { |dates| dates.created_at }
    #Nehmen Sie die Datumsnotation in jeder Anweisung einzeln heraus und ändern Sie sie
    @dates.each do |a|
      gon.date << a.strftime("%Y Jahr%m Monat%d Tag")
    end


    #Körpergewicht
    if user_signed_in?
      gon.weight = current_user.posts.group("date(created_at)").select(:weight).map { |weight| weight[:weight] }
    else
      gon.weight = @sampleuser.posts.group("date(created_at)").select(:weight).map { |weight| weight[:weight] }
    end
  end

Recommended Posts

Ein Fehler ist aufgetreten, weil die only_full_group_by von sql_mode nicht beobachtet wurde.
[Abgelehnt] Ein Memorandum, da während der Bereitstellung in Heroku ein Fehler aufgetreten ist
Ein Beispiel für einen FactoryBot-Fehler [KeyError: Factory nicht registriert: "Benutzer"]
[Nicht autorisierter Vorgang] Ein Memorandum, da beim Erstellen einer EC2-Instanz ein Fehler aufgetreten ist.
Bei der Einführung von JOOQ in Spring Boot wurde eine Geschichte behandelt, die behandelt wurde, weil bei Liquidbase ein Fehler aufgetreten ist