How to “group by” in strict string comparation when sql_mode=only_full_group_by is setted in MySql?

ε祈祈猫儿з 提交于 2019-12-12 03:54:35

问题


I want to group by t0.method in strict string comparation, i.e. "GET ", "GET" and "get" in different group, so a BINARY is added in front of the t0.method field which appears in the group by sentence. but I can't add a BINARY to this field which appears in the select sentence, since this will cause an encoding problem when non-ascii characters appears in the data.

So following is the SQL query I finally get:

SELECT `t0`.`method` AS `d0`,
  SUM(`t0`.`success`) AS `m0`
FROM `invoke_statistics` AS `t0`
GROUP BY BINARY `t0`.`method`
LIMIT 20000

But unfortunately, I got the following error message then..

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 't0.method' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

So, what is the correct way to do all this without causing any encoding problem or incompatibility problem with the "sql_mode=only_full_group_by" things?

NOTE:

  1. I'm not able to modify the sql_mode option.
  2. I'm not able to make sure that there is no non-ascii characters appears in the data
  3. I'm not able to know what char set is used before generate a query. so the collate utf8_bin or similar things is not able to work since it may cause some errors like COLLATION 'UTF8_BIN' is not valid for CHARACTER SET 'latin1'

I'm doing something about code generation, so the other's answer which depends on a lot of assumptions can't solve my problem, I need some general solution


回答1:


Both of the following work when the SQL mode includes ONLY_FULL_GROUP_BY:

Make your grouping column part of the select-list:

SELECT BINARY `t0`.`method` AS `d0`,
  SUM(`t0`.`success`) AS `m0`
FROM `invoke_statistics` AS `t0`
GROUP BY BINARY `t0`.`method`
LIMIT 20000

Or make your select-list use an aggregate function:

SELECT MAX(`t0`.`method`) AS `d0`,
  SUM(`t0`.`success`) AS `m0`
FROM `invoke_statistics` AS `t0`
GROUP BY BINARY `t0`.`method`
LIMIT 20000

I tested both of these queries on MySQL 8.0 DMR.




回答2:


(There seem to be two questions rolled into one. This addresses the collation problem.)

Plan A

The "right" answer is to change the collation in the table definition:

CREATE TABLE ...
    method ... COLLATE xxx_bin
    ...

Where xxx is the charset involved. That is (apparently), latin1_bin. ("Latin1_General_CS_AS" comes from some other vendor, not MySQL.)

Caveat: This will affect all other comparisons (WHERE, ORDER BY, =) involving the column method. (This may or may not be an issue.)

Plan B

The way to do it in the query is

... GROUP BY method COLLATE latin1_bin ...

A COLLATE clause can be tacked onto a variety of things, including comparisons and ORDER BY. But, note, it prevents the use of an index for optimization.



来源:https://stackoverflow.com/questions/40396426/how-to-group-by-in-strict-string-comparation-when-sql-mode-only-full-group-by

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!