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 |
+----+---------+---------+---------+----------+-----------+------------+---------------+--------------+------------+--------+---------------------+---------------------+

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... :-)


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).


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


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.


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

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.


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 !!!


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

3

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


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.


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

Entre abaixo

[mysqld]
sql_mode = ""

Ctrl + O => Y = Ctrl + X

> sudo service mysql restart

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`

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.


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


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.


-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


-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.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.