在MySql中執行查詢時與only_full_group_by相關的錯誤

本文翻譯自:Error related to only_full_group_by when executing a query in MySql

I have upgraded my system and have installed MySql 5.7.9 with php for a web application I am working on. 我已經升級了系統,併爲正在使用的Web應用程序安裝了帶有PHP的MySql 5.7.9。 I have a query that is dynamically created, and when run in older versions of MySql it works fine. 我有一個動態創建的查詢,當在舊版本的MySql中運行時,它運行良好。 Since upgrading to 5.7 I get this error: 自升級到5.7以來,出現此錯誤:

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'support_desk.mod_users_groups.group_id' which is not functionally dependent on columns in GROUP BY clause; SELECT列表的表達式#1不在GROUP BY子句中,並且包含未聚合的列'support_desk.mod_users_groups.group_id',該列在功能上不依賴於GROUP BY子句中的列; this is incompatible with sql_mode=only_full_group_by 這與sql_mode = only_full_group_by不兼容

Note the Manual page for Mysql 5.7 on the topic of Server SQL Modes . 請注意有關服務器SQL模式主題的Mysql 5.7手冊頁。

This is the query that is giving me trouble: 這是給我帶來麻煩的查詢:

SELECT mod_users_groups.group_id AS 'value', 
       group_name AS 'text' 
FROM mod_users_groups
LEFT JOIN mod_users_data ON mod_users_groups.group_id = mod_users_data.group_id 
WHERE  mod_users_groups.active = 1 
  AND mod_users_groups.department_id = 1 
  AND mod_users_groups.manage_work_orders = 1 
  AND group_name != 'root' 
  AND group_name != 'superuser' 
GROUP BY group_name 
HAVING COUNT(`user_id`) > 0 
ORDER BY group_name

I did some googling on the issue, but I don't understand only_full_group_by enough to figure out what I need to do to fix the query. 我在這個問題上做了一些谷歌搜索,但是我對only_full_group_by理解不足以弄清楚我需要做什麼來解決查詢。 Can I just turn off the only_full_group_by option, or is there something else I need to do? 我可以僅關閉only_full_group_by選項,還是需要做其他事情?

Let me know if you need more information. 如果您需要更多信息,請與我們聯繫。


#1樓

參考:https://stackoom.com/question/2J8uk/在MySql中執行查詢時與only-full-group-by相關的錯誤


#2樓

I would just add group_id to the GROUP BY . 我只是將group_id添加到GROUP BY

When SELECT ing a column that is not part of the GROUP BY there could be multiple values for that column within the groups, but there will only be space for a single value in the results. SELECT不屬於GROUP BY列時,組中該列可能有多個值,但結果中只有一個值的空間。 So, the database usually needs to be told exactly how to make those multiple values into one value. 因此, 通常需要準確告知數據庫如何將多個值變成一個值。 Commonly, this is done with an aggregate function like COUNT() , SUM() , MAX() etc... I say usually because most other popular database systems insist on this. 通常,這是通過諸如COUNT()SUM()MAX()等聚合函數來完成的。我之所以這樣說因爲大多數其他流行的數據庫系統都堅持這樣做。 However, in MySQL prior to version 5.7 the default behaviour has been more forgiving because it will not complain and then arbitrarily choose any value ! 但是,在版本5.7之前的MySQL中,默認行爲更爲寬容,因爲它不會抱怨,然後可以任意選擇任何值 It also has an ANY_VALUE() function that could be used as another solution to this question if you really needed the same behaviour as before. 如果您確實需要與以前相同的行爲,它還具有ANY_VALUE()函數,可以用作該問題的另一個解決方案。 This flexibility comes at a cost because it is non-deterministic, so I would not recommend it unless you have a very good reason for needing it. 這種靈活性要付出一定的代價,因爲它是不確定性的,因此除非您有充分的理由需要它,否則我不建議您這樣做。 MySQL are now turning on the only_full_group_by setting by default for good reasons, so it's best to get used to it and make your queries comply with it. 由於種種原因,MySQL現在默認情況下默認啓用了only_full_group_by設置,因此最好習慣它並使查詢符合它。

So why my simple answer above? 那麼,爲什麼我上面的簡單答案呢? I've made a couple of assumptions: 我做了兩個假設:

1) the group_id is unique. 1) group_id是唯一的。 Seems reasonable, it is an 'ID' after all. 似乎合理,畢竟它是一個“ ID”。

2) the group_name is also unique. 2) group_name也是唯一的。 This may not be such a reasonable assumption. 這可能不是一個合理的假設。 If this is not the case and you have some duplicate group_names and you then follow my advice to add group_id to the GROUP BY , you may find that you now get more results than before because the groups with the same name will now have separate rows in the results. 如果不是這種情況,並且您有一些重複的group_names ,然後按照我的建議將group_id添加到GROUP BY ,您可能會發現現在獲得的結果比以前更多,因爲同名的組現在將在其中具有單獨的行。結果。 To me, this would be better than having these duplicate groups hidden because the database has quietly selected a value arbitrarily! 對我來說,這比隱藏這些重複的組更好,因爲數據庫已悄悄地選擇了一個值!

It's also good practice to qualify all the columns with their table name or alias when there's more than one table involved... 當涉及多個表時,最好用表名或別名來限定所有列。

SELECT 
  g.group_id AS 'value', 
  g.group_name AS 'text' 
FROM mod_users_groups g
LEFT JOIN mod_users_data d ON g.group_id = d.group_id 
WHERE g.active = 1 
  AND g.department_id = 1 
  AND g.manage_work_orders = 1 
  AND g.group_name != 'root' 
  AND g.group_name != 'superuser' 
GROUP BY 
  g.group_name, 
  g.group_id 
HAVING COUNT(d.user_id) > 0 
ORDER BY g.group_name

#3樓

You can try to disable the only_full_group_by setting by executing the following: 您可以通過執行以下操作來嘗試禁用only_full_group_by設置:

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';

MySQL 8 does not accept NO_AUTO_CREATE_USER so that needs to be removed. MySQL 8不接受NO_AUTO_CREATE_USER因此需要刪除它。


#4樓

If you don't want to make any changes in your current query then follow the below steps - 如果您不想在當前查詢中進行任何更改,請按照以下步驟操作-

  1. vagrant ssh into your box 流浪者ssh放入您的盒子
  2. Type: sudo vim /etc/mysql/my.cnf 鍵入: sudo vim /etc/mysql/my.cnf
  3. Scroll to the bottom of file and type A to enter insert mode 滾動到文件底部,然後鍵入A進入插入模式
  4. Copy and paste 複製和粘貼

     [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 
  5. Type esc to exit input mode 鍵入esc退出輸入模式

  6. Type :wq to save and close vim. 輸入:wq保存並關閉vim。
  7. Type sudo service mysql restart to restart MySQL. 輸入sudo service mysql restart重啓MySQL。

#5樓

you can turn off the warning message as explained in the other answers or you can understand what's happening and fix it. 您可以按照其他答案中的說明關閉警告消息,也可以瞭解發生的情況並進行修復。

As of MySQL 5.7.5, the default SQL mode includes ONLY_FULL_GROUP_BY which means when you are grouping rows and then selecting something out of that groups, you need to explicitly say which row should that selection be made from. 從MySQL 5.7.5開始,默認的SQL模式包括ONLY_FULL_GROUP_BY ,這意味着當您將行分組然後從該組中選擇某項時,您需要明確說出應該從哪 一行進行選擇。 Mysql需要知道您要查找的組中的哪一行,這給了您兩個選擇

Mysql needs to know which row in the group you're looking for, which gives you two options Mysql需要知道您要查找的組中的哪一行,這給了您兩個選擇

  • You can also add the column you want to the group statement group by rect.color, rect.value which can be what you want in some cases otherwise would return duplicate results with the same color which you may not want 您還可以group by rect.color, rect.value將所需的列添加到group語句group by rect.color, rect.value在某些情況下group by rect.color, rect.value可能是您想要的列,否則將返回重複的結果,並且顏色可能與您不希望的相同
  • you could also use aggregate functions of mysql to indicate which row you are looking for inside the groups like AVG() MIN() MAX() complete list 您還可以使用mysql的聚合函數來指示要在組中查找的行,例如AVG() MIN() MAX() 完整列表
  • AND finally you can use ANY_VALUE() if you are sure that all the results inside the group are the same. 最後,如果您確定組內的所有結果都相同,則可以使用ANY_VALUE() doc doc

#6樓

This is what helped me to understand the entire issue: 這就是幫助我瞭解整個問題的原因:

  1. https://stackoverflow.com/a/20074634/1066234 https://stackoverflow.com/a/20074634/1066234
  2. https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

And in the following another example of a problematic query. 在下面的另一個有問題查詢的示例中。

Problematic: 有問題的:

SELECT COUNT(*) as attempts, SUM(elapsed) as elapsedtotal, userid, timestamp, questionid, answerid, SUM(correct) as correct, elapsed, ipaddress FROM `gameplay`
                        WHERE timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY)
                        AND cookieid = #

Solved by adding this to the end: 通過將其添加到末尾來解決:

  GROUP BY timestamp, userid, cookieid, questionid, answerid, elapsed, ipaddress

Note: See the error message in PHP, it tells you where the problem lies. 注意:請參閱PHP中的錯誤消息,它告訴您問題出在哪裏。

Example: 例:

MySQL query error 1140: In aggregated query without GROUP BY, expression #4 of SELECT list contains nonaggregated column 'db.gameplay.timestamp'; MySQL查詢錯誤1140:在沒有GROUP BY的聚合查詢中,SELECT列表的表達式#4包含非聚合列'db.gameplay.timestamp'; this is incompatible with sql_mode=only_full_group_by - Query: SELECT COUNT(*) as attempts, SUM(elapsed) as elapsedtotal, userid, timestamp, questionid, answerid, SUM(correct) as correct, elapsed, ipaddress FROM gameplay WHERE timestamp >= DATE_SUB(NOW(), INTERVAL 1 DAY) AND userid = 1 這與sql_mode = only_full_group_by不兼容-查詢:SELECT COUNT(*)作爲嘗試,SUM(elapsed)作爲經過,total,userid,timestamp,questionid,answerid,SUM(正確)爲正確,經過,ipaddress from gameWhere時間戳> = DATE_SUB (現在(),間隔1天)和用戶ID = 1

In this case, expression #4 was missing in the GROUP BY. 在這種情況下,GROUP BY中缺少表達式#4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章