A lista SELECT não está na cláusula GROUP BY e contém coluna não agregada ... incompatível com sql_mode = only_full_group_by

115

AM usando MySQL 5.7.13 em meu PC com Windows com servidor WAMP

Aqui, meu problema é ao executar esta consulta

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

Estou sempre recebendo erros como este

A expressão # 1 da lista SELECT não está na cláusula GROUP BY e contém a coluna não agregada 'returntr_prod.tbl_customer_pod_uploads.id' que não é funcionalmente dependente de colunas na cláusula GROUP BY; isso é incompatível com sql_mode = only_full_group_by

Você pode me dizer a melhor solução ...

Eu preciso de resultados como

+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+
| 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
fonte
12
Não use SELECT *.
shmosel
estão dizendo assim: SELECT id FROM tbl_customer_pod_uploadsWHERE load_id= '78' AND status= 'Active' GROUP BYproof_type
Dhanu K
2
Se você deseja compatibilidade para consultas antigas, pode desligar o only_full_group_bymodo SQL.
Barmar
4
Tente usar ANY_VALUE (proof_type): dev.mysql.com/doc/refman/5.7/en/group-by-handling.html SELECT *, ANY_VALUE (proof_type) FROM tbl_customer_pod_uploadsWHERE load_id= '78' AND status= 'Ativo' GROUP BYproof_type
AlexGach

Respostas:

228

este

A expressão # 1 da lista SELECT não está na cláusula GROUP BY e contém a coluna não agregada 'returntr_prod.tbl_customer_pod_uploads.id' que não é funcionalmente dependente de colunas na cláusula GROUP BY; isso é incompatível com sql_mode = only_full_group_by

será simplesmente resolvido alterando o modo sql no MySQL por este comando,

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

Isso também funciona para mim .. Eu usei isso, porque em meu projeto existem muitas consultas como esta, então eu apenas alterei este modo sql para only_full_group_by

Obrigado... :-)

Dhanu K
fonte
14
Funciona para mim!. Você salva meu dia. Lembre-se de REINICIAR O SERVIÇO MYSQL
marcode_ely
2
Se eu estiver usando o codeigniter e quiser executar no modelo, como eu o usaria? Pode me ajudar ? @marcode_ely
DhavalThakor
@DhavalThakor, depois de executar esta consulta em seu servidor, você não precisa executar novamente e novamente. então você não precisa colocá-lo em seu modelo
Dhanu K
2
MySQL 5.7.29, não foi necessário reiniciar o serviço
Taavi
Estou usando a versão do servidor: 5.7.31-0ubuntu0.16.04.1 - (Ubuntu), e sempre que eu inicio minha máquina, eu a defino todas as vezes. Existe alguma correção permanente para isso?
Arpita Hunka
71

Quando o only_full_group_bymodo MySQL está ativado, isso significa que regras estritas ANSI SQL serão aplicadas durante o uso GROUP BY. Com relação à sua consulta, isso significa que, se você for GROUP BYda proof_typecoluna, poderá selecionar apenas duas coisas:

  • a proof_typecoluna, ou
  • agregados de qualquer outra coluna


Por "agregados" de outras colunas, quer dizer usando uma função de agregação, tais como MIN(), MAX(), ou AVG()com outra coluna. Portanto, no seu caso, a seguinte consulta seria válida:

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

A grande maioria das GROUP BYperguntas do MySQL que vejo no SO tem o modo estrito desativado, então a consulta está em execução, mas com resultados incorretos. No seu caso, a consulta não será executada, forçando você a pensar no que realmente deseja fazer.

Nota: O ANSI SQL estende o que pode ser selecionado GROUP BY, incluindo também colunas que são funcionalmente dependentes da (s) coluna (s) selecionada (s). Um exemplo de dependência funcional seria o agrupamento por uma coluna de chave primária em uma tabela. Como a chave primária tem garantia de ser única para cada registro, portanto, o valor de qualquer outra coluna também seria determinado. MySQL é um dos bancos de dados que permite isso (SQL Server e Oracle não AFAIK).

Tim Biegeleisen
fonte
2
Apenas uma observação: o resultado não é incorreto (segue as regras do MySQL), mas é imprevisível, o que significa que as colunas que não fazem parte do grupo por e não agregadas (e não dependem funcionalmente) retornarão um valor 'aleatório' do grupo correspondente. Como afirma o manual: "o servidor é livre para escolher qualquer valor de cada grupo"
Pred
Violar o agrupamento estrito não produz necessariamente resultados incorretos. Normalmente faço isso quando os campos são idênticos (por exemplo, uma junção um-para-muitos). E mesmo que não seja garantido, selecionar uma linha arbitrária geralmente não será mais incorreto do que usar uma função de agregação ou adicionar um nível de agrupamento.
shmosel
1
1 para mim. Não tenho ideia de por que a resposta "aceita" acima foi aceita. Sua maneira é a maneira correta e a resposta aceita é a correção de hacky usual que levará a mais problemas no futuro.
Jcov
1
@Jcov ... e não poderia concordar mais com seu comentário +1. Desativar a restrição ANSI GROUP BYquase sempre é uma má ideia. Me assusta que tantos usuários estejam seguindo conselhos errados e usando-os.
Tim Biegeleisen
1
@TimBiegeleisen bem-vindo ao desenvolvimento moderno de copiar e colar. "Eu não preciso pensar, alguém que leu algo aleatório em algum lugar de uma fonte não confiável já pensou por mim".
Jcov
38

Use qualquer solução

(1) PHPMyAdmin

se você estiver usando phpMyAdmin, altere a configuração " sql_mode " conforme mencionado na imagem abaixo. insira a descrição da imagem aqui

Edite a variável "modo sql" e remova o texto "ONLY_FULL_GROUP_BY" do valor

(2) SQL / Prompt de comando Execute o comando abaixo.

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

(3) ** Não use SELECT ***

Use a coluna relevante na consulta SELECT. relevante significa colunas, que vêm na cláusula "group by" ou coluna com a função agregada (MAX, MIN, SUM, COUNT etc)


Nota importante

As alterações feitas usando o ponto (1) OU o ponto (2) não o definirão PERMANENTEMENTE e ele será revertido após cada reinicialização.

Portanto, você deve definir isso em seu arquivo de configuração (por exemplo, /etc/mysql/my.cnf na seção [mysqld]), para que as alterações permaneçam em vigor após a reinicialização do MySQL:

Arquivo de configuração : /etc/mysql/my.cnf

Nome da variável : sql_mode OR sql-mode

Rakesh Soni
fonte
19

O método abaixo resolveu meu problema:

No ubuntu

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

digite A para entrar no modo de inserção

Na última linha, cole o código de duas linhas abaixo:

[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

Digite esc para sair do modo de entrada

Type :wq to save and close vim.

Digite sudo service mysql restartpara reiniciar o MySQL.

Anand Huded
fonte
1
obrigado, funcionou! em cent os, whm, my.cnf estava localizado em sudo vi /etc/my.cnf
Reejesh PK
17

Você pode desativar sql_mode = only_full_group_by por algum comando, você pode tentar isso por terminal ou MySql IDE

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
fonte
10

No Ubuntu

Passo 1:

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

Etapa 2: vá para a última linha e adicione o seguinte

sql_mode = ""

Etapa 3: Salvar

Etapa 4: Reinicie o servidor mysql.

Gullu Mutullu
fonte
9

Para que a consulta seja válida no SQL92, a coluna name deve ser omitida da lista de seleção ou nomeada na cláusula GROUP BY.

O SQL99 e posteriores permitem tais não agregados por recurso opcional T301 se forem funcionalmente dependentes das colunas GROUP BY: Se tal relação existir entre o nome e o custid, a consulta é válida. Esse seria o caso, por exemplo, se fosse custeada uma chave primária de clientes.

MySQL 5.7.5 e superior implementa detecção de dependência funcional. Se o modo ONLY_FULL_GROUP_BY SQL estiver habilitado (o que é por padrão), o MySQL rejeita as consultas para as quais a lista de seleção, condição HAVING ou lista ORDER BY se referem a colunas não agregadas que não são nomeadas na cláusula GROUP BY nem são funcionalmente dependentes delas .

via MySQL :: MySQL 5.7 Reference Manual :: 12.19.3 MySQL Handling of GROUP BY

Você pode resolvê-lo alterando o modo sql com este comando:

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

e ... lembre-se de reconectar o banco de dados !!!

ElliotMok
fonte
5

vá para o phpmyadmin e abra o console e execute esta solicitação

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

Procure por "modo SQL" se estiver usando PhpMyAdmin e retire o valor:, ONLY_FULL_GROUP_BYacabei de fazer e está tudo bem.

Mr_Bull
fonte
2

Pelo que parece, acho que agrupar por várias colunas / campos não vai prejudicar o seu resultado. Por que você não tenta adicionar ao grupo desta forma:

GROUP BY `proof_type`, `id`

Isso irá agrupar proof_typeprimeiro então id. Espero que isso não altere os resultados. Em alguns / na maioria dos casos, agrupar por várias colunas dá resultados errados.

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

Entre abaixo

[mysqld]
sql_mode = ""

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart
Sundar
fonte
2

Olá, em vez de pegar todas as colunas, pegue apenas o que precisa usando ANY_VALUE(column_name). Está funcionando perfeitamente. Apenas verifique.

Por exemplo:

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
fonte
1
  1. Faça login no phpMyAdmin
  2. Navegue até: Servidor: localhost: 3306 e não selecione nenhum banco de dados
  3. Clique nas variáveis ​​do menu superior
  4. Procure por "modo sql" e edite o valor correspondente para: NO_ENGINE_SUBSTITUTION

Isso é tudo.

Eu fiz isso no meu Ec2 e funcionou como um encanto.

PrafulPravin
fonte
1

Esta é uma maneira muito rápida e fácil de configurá-lo permanentemente

NB: a execução SET GLOBAL sql_mode=(SELECT REPLACE(@@sql_mode,'ONLY_FULL_GROUP_BY','')); é temporária e na reinicialização do servidor você ainda vai acabar com o erro. Para corrigir isso permanentemente, faça o seguinte

  1. Faça login no seu servidor como root
  2. em seu terminal executado wget https://gist.githubusercontent.com/nfourtythree/90fb8ef5eeafdf478f522720314c60bd/raw/disable-strict-mode.sh
  3. Torne o script executável executando chmod +x disable-strict-mode.sh
  4. Execute o script executando ./disable-strict-mode.sh

E pronto, as alterações serão feitas no mysql e ele será reiniciado

Nelson Bwogora
fonte
0

Atualização para MySQL 8.0

Você sql-modenão terá NO_AUTO_CREATE_USER, pois foi removido conforme mencionado aqui - how-to-set-sql-mode-in-my-cnf-in-mysql-8

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

Além disso, se alguém não tiver um my.cnfarquivo, deve criar um novo /etc/my.cnfe adicionar as linhas acima.

Gautam
fonte
-2

No seu my.ini, escreva isto:

[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"

depende da sua versão. Ou:

[mysqld]
sql_mode = ""

ou simplesmente remova este: ONLY_FULL_GROUP_BY

Gary Carranza Sebastian
fonte
-2

Abra o painel WAMP e abra o arquivo de configuração do MySQL. Nele, procure por "sql_mode" se você encontrá-lo, configure-o para "", caso contrário, adicione sql_mode = "" ao arquivo.

Reinicie o servidor MySQL e você está pronto para ir ...

codificação feliz.

Mohd Samgan Khan
fonte