0

I have 2 Mysql databases:

  • #1 is created on Raspbian Raspberry pi 4
  • #2 is created on virtual Ubuntu server.

I have been interacting with Mysql DB that is created by Raspberry pi 4 without any issues but now I want to migrate all the database to the virtual Ubuntu server to make my system more flexible.

After installing all the required modules on my ubuntu server, I have launched my python code and notice that it is not working properly. I get some mysql error regarding the GROUP BY statement:

mysql.connector.errors.ProgrammingError: 1055 (42000): Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test.Operation_1109360548.ID' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

The query that I am trying to execute:

sql = "SELECT Serial,ID,count(*) FROM {table} GROUP BY Serial"
cur.execute(sql.format(table=table_name))

And my database table looks like:

database table

QUESTIONS

  1. Could someone suggest why it would allow me to execute this query on mysql DB running on Raspbian but doesn't allow me on UBUNTU mysql?

  2. How to solve this issue? I do not see any problems with this query. I have heard that you can modify mysql.cnf but that is not the best solution

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
TheBestPlayer
  • 324
  • 2
  • 13
  • Related https://dba.stackexchange.com/questions/294989/is-mysql-breaking-the-standard-by-allowing-selecting-columns-that-are-not-part-o and https://stackoverflow.com/questions/1225144/why-does-mysql-allow-group-by-queries-without-aggregate-functions – snakecharmerb Jul 30 '21 at 12:05
  • which ID do you want every column has to be in the GROUP BY or have a aggregation funktion – nbk Jul 30 '21 at 12:07
  • I dont really understand what is the problem. There can be multiple UNIQUE Serial values with the same ID. This way, my program knows that there an be alternatives.. Its complicated system I dont think I can explain it all here. My biggest concern is how can it work my on Raspbian mysql but not work on ubuntu? I am executing exact same queries – TheBestPlayer Jul 30 '21 at 12:19

2 Answers2

0

SERIAL is a DATATYPE in MySQL. So you must put it in backquotes to use as fieldname:

sql = "SELECT `Serial`,ID,count(*) 
        FROM {table} 
        GROUP BY `Serial`"
cur.execute(sql.format(table=table_name))

see : https://mariadb.com/docs/reference/mdb/data-types/SERIAL/

RiggsFolly
  • 93,638
  • 21
  • 103
  • 149
Bernd Buffen
  • 14,525
  • 2
  • 24
  • 39
0

It depends on what you are trying to achieve, if for example you have a database: S-Serial, I-ID

S|I
1|2
1|3
2|4
3|5
3|4

You aggregate serial to values 1,2,3, but what to do with ID? should S=1 have ID=2 or ID=3? You could tell your query what to do with ID, what type of aggregation (e.g. MAX, MIN, AVG)

You can let the database handle it, but to do so you need to disable ONLY_FULL_GROUP_BY clause, and that's the consequence: The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. And to do this I'll just give you a link: Disable ONLY_FULL_GROUP_BY

Example:

SELECT Serial, MIN(ID), COUNT(*) FROM TABLE_NAME
GROUP BY Serial

On the other hand, if your database looks like that:

S|I
1|2
2|3
3|1
4|4
5|5

So the values of Serial and ID are unique couples, you should group by both of these columns, so your query could look like this:

SELECT Serial, ID, COUNT(*) FROM TABLE_NAME
GROUP BY Serial,ID
Lidbey
  • 251
  • 1
  • 12
  • Thanks for the answer. I have tried to simply add ```GROUP BY Serial,ID``` instead of just ```GROUP BY Serial``` and that seems to work for now. I am now trying to understand more about MIN MAX and etc. The tricky thing is that there might be multiple unique serial values but they all have matching ID's. IF that is the case, my system will determine which one is more convenient and select it. – TheBestPlayer Jul 30 '21 at 12:23
  • If there can be multiple IDs for single serial value, you should put any aggregate function on column ID which will tell the query which one to choose, if you want to let the engine handle it, you can disable ONLY_FULL_GROUP_BY clause for database, but as I have just found: `The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate.`. It is better to think about which value is the most interesting to show :) Or maybe you want to use group_concat to show concatenated strings made of IDs in a single column – Lidbey Jul 30 '21 at 12:25
  • You keep using word aggregate. Please can you tell me what exactly it means when it comes to mysql? ```The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate```. What does that mean to me? Do I care about it? Also, how about this solution ```GROUP BY Serial,ID```. Do you think thats not good enough because it seems to work? – TheBestPlayer Jul 30 '21 at 12:31
  • Group by clause is made for aggregations - maybe it is not a dictionary definition, but I would say it is making one value out of many. So in your case, you aggregate to get COUNT(*) - limiting your records in a table to only unique Serial and ID, and aggregating all other values to get the COUNT(\*). Imagine 1 collumn table with values `1 2 3 1 2 3 1 2 3 3 3 3`, with aggregation COUNT(\*) you will get: `V|* 1|3 2|3 3|6` And about the server is free to choose: Let's think about your example where you have `S=2 I=3` and `S=2 I=4` what `I` to list with `S=2`? – Lidbey Jul 30 '21 at 12:35
  • And maybe even think about database that holds revenue: Client ID=0 pays 100$, Client ID=1 pays 200$, Client ID=0 pays 400$, you would probably like to aggregate that Client ID=0 pays total of 500$, and client ID=1 pays total of 200$ - that's what aggregation with SUM() would do :) – Lidbey Jul 30 '21 at 12:48
  • Okay I think I understand now. Perhaps the database on the Raspberry pi 4 had disabled the ONLY_FULL_GROUP_BY by default therefore it worked. I have analyzed my database a little bit and it seems that my system is OK with server selecting a random ID so this could be a solution. Another simple solution is to ```GROUP BY Serial,ID``` but I need to do more testing to ensure this will not cause any problems in the future even though it seems to work for a few quick tests I did. Anyway, thank you a lot for explaining – TheBestPlayer Jul 30 '21 at 13:23