MySql에서 쿼리를 실행할 때 only_full_group_by와 관련된 오류
시스템을 업그레이드하고 작업중 인 웹 응용 프로그램 용 PHP로 MySql 5.7.9를 설치했습니다. 동적으로 생성 된 쿼리가 있으며 이전 버전의 MySql에서 실행될 때 정상적으로 작동합니다. 5.7로 업그레이드 한 후이 오류가 발생합니다.
SELECT 목록의 식 # 1은 GROUP BY 절에 없으며 GROUP BY 절의 열에 기능적으로 종속되지 않는 집계되지 않은 열 'support_desk.mod_users_groups.group_id'를 포함합니다. sql_mode = only_full_group_by와 호환되지 않습니다
서버 SQL 모드 주제에서 Mysql 5.7의 매뉴얼 페이지를 참고하십시오 .
이것은 나에게 문제를 일으키는 쿼리입니다.
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
이 문제에 대해 인터넷 검색을 수행했지만 only_full_group_by
쿼리를 수정하기 위해 수행해야 할 작업을 파악할 만큼 충분히 이해하지 못했습니다 . only_full_group_by
옵션을 끌 수 있습니까 ? 아니면 다른 조치가 필요합니까?
더 자세한 정보가 필요하면 알려주십시오.
난 그냥 추가 할 group_id
받는 사람 GROUP BY
.
하면 SELECT
의 일부가 열 보내고 GROUP BY
그룹 내의 그 열에 대한 복수의 값이있을 수 있지만, 단지 하나의 결과 값을위한 공간이있을 것이다. 따라서 데이터베이스는 일반적으로 여러 값을 하나의 값으로 만드는 방법을 정확하게 알려야합니다. 일반적으로,이이 같은 집계 함수와 함께 이루어집니다 COUNT()
, SUM()
, MAX()
등 ... 내가 말할 일반적으로 대부분의 다른 인기있는 데이터베이스 시스템이 주장하기 때문이다. 그러나 버전 5.7 이전의 MySQL에서는 기본 동작이 불평하지 않고 임의로 값을 선택하기 때문에 더 관대했습니다 ! 그것은 또한ANY_VALUE()
이전과 동일한 동작이 필요한 경우이 질문에 대한 다른 솔루션으로 사용할 수있는 함수입니다. 이 유연성은 비결정 적이기 때문에 비용이 많이 들기 때문에 필요한 이유가 없다면 권장하지 않습니다. MySQL은 이제 only_full_group_by
좋은 이유로 기본적으로 설정을 설정하고 있으므로 익숙해 져 쿼리를 준수하는 것이 가장 좋습니다.
왜 내 간단한 대답이 위입니까? 나는 몇 가지 가정을 만들었습니다.
1) group_id
는 독특합니다. 합리적인 것처럼 보이며 결국 'ID'입니다.
2) group_name
또한 독특합니다. 이것은 그렇게 합리적인 가정이 아닐 수도 있습니다. 그렇지 않은 경우 중복 된 부분이 group_names
있고 내 조언에 따라에 추가 group_id
하면 GROUP BY
이름이 같은 그룹에 결과에 별도의 행이 있으므로 이전보다 더 많은 결과를 얻을 수 있습니다. 데이터베이스가 임의로 값을 임의로 선택했기 때문에 중복 그룹을 숨기는 것보다 나을 것입니다.
또한 둘 이상의 테이블이 관련된 경우 모든 열을 테이블 이름 또는 별명으로 규정하는 것이 좋습니다.
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
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은 NO_AUTO_CREATE_USER
제거 할 필요 가 없으므로 허용하지 않습니다 .
다른 답변에 설명 된대로 경고 메시지를 끄거나 진행 상황을 이해 하고 수정할 수 있습니다.
MySQL 5.7.5부터 기본 SQL 모드에는 ONLY_FULL_GROUP_BY 가 포함되어 있습니다. 이는 행을 그룹화 한 다음 해당 그룹에서 무언가를 선택할 때 선택해야 할 행 을 명시 적으로 말해야 합니다.
MySQL은 당신이 찾고있는 그룹의 어떤 행을 알아야하며, 두 가지 옵션이 있습니다
- 원하는 열을 그룹 문에 추가 할 수도 있습니다.
group by rect.color, rect.value
어떤 경우에는 원하지 않을 수도있는 동일한 색상으로 중복 결과를 반환 할 수 있습니다 - mysql의 집계 함수 를 사용 하여 전체 목록 과 같이 그룹 내에서 찾고있는 행을 나타낼 수도 있습니다
AVG()
MIN()
MAX()
- 마지막으로
ANY_VALUE()
그룹 내부의 모든 결과가 동일한 지 확인할 수 있습니다. 문서
현재 검색어를 변경하지 않으려면 아래 단계를 따르십시오.
- 당신의 상자에 방랑 ssh
- 유형:
sudo vim /etc/mysql/my.cnf
- 파일 하단으로 스크롤하여 입력
A
하여 삽입 모드로 들어갑니다. 복사 및 붙여 넣기
[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
입력
esc
종료 입력 모드로:wq
vim을 저장하고 닫으려면 입력하십시오 .sudo service mysql restart
MySQL을 다시 시작하려면 입력하십시오 .
ANY_VALUE()
집계되지 않은 열을 참조하는 데 사용 합니다.
에서 의 MySQL 5.7 문서 :
집계되지 않은 열을 참조하는 데
ONLY_FULL_GROUP_BY
사용하여 비활성화하지 않고도 동일한 효과를 얻을 수 있습니다ANY_VALUE()
....
ONLY_FULL_GROUP_BY
선택 목록의 집계되지 않은 주소 열이GROUP BY
절 에서 이름이 지정되지 않았으므로이 쿼리는 사용으로 유효하지 않을 수 있습니다 .SELECT name, address, MAX(age) FROM t GROUP BY name;
...
주어진 데이터 세트에 대해 실제로 각 이름 값이 실제로 주소 값을 고유하게 결정하는 경우 주소는 사실상 기능적으로 이름에 의존합니다. MySQL에게 쿼리를 수락하도록하려면 다음
ANY_VALUE()
함수를 사용할 수 있습니다 .SELECT name, ANY_VALUE(address), MAX(age) FROM t GROUP BY name;
이 오류가 무엇인지 설명하려고 노력할 것입니다.
MySQL 5.7.5부터 옵션 ONLY_FULL_GROUP_BY
이 기본적으로 활성화되어 있습니다.
따라서 표준 SQL92 이하에 따르면 :
선택 목록, HAVING 조건 또는 ORDER BY 목록이 GROUP BY 절에 이름이 지정되지 않았거나 기능적으로 GROUP BY 열에 종속되지 않은 집계되지 않은 열을 참조하는 쿼리는 허용하지 않습니다.
( 문서에서 더 읽기 )
예를 들어,
SELECT * FROM `users` GROUP BY `name`;
위의 쿼리를 실행하면 오류 메시지가 나타납니다.
# 1055-SELECT 목록의 식 # 1은 GROUP BY 절에 없으며 GROUP BY 절의 열에 기능적으로 의존하지 않는 집계되지 않은 열 'testsite.user.id'를 포함합니다. sql_mode = only_full_group_by와 호환되지 않습니다
왜?
MySQL은 정확히 이해하지 못하기 때문에 그룹화 된 레코드에서 검색 할 특정 값이 무엇인지, 이것이 요점입니다.
IE는 users
테이블 에이 레코드가 있다고 말할 수 있습니다 .
그리고 위에 표시된 잘못된 쿼리를 실행합니다.
그리고 name과 함께 3 개의 레코드가 John
있고 훌륭 하기 때문에 위에 표시된 오류가 발생 하지만 모두 email
필드 값 이 다릅니다 .
따라서 MySQL은 그룹화 된 레코드로 반환 할 대상을 이해하지 못합니다.
다음과 같이 간단히 쿼리를 변경하여이 문제를 해결할 수 있습니다.
SELECT `name` FROM `users` GROUP BY `name`
또한 SELECT 섹션에 더 많은 필드를 추가하고 싶을 수도 있지만 집계되지 않은 경우 사용할 수는 있지만 사용할 수는 없습니다 (그러나 권장하지는 않음).
SELECT ANY_VALUE(`id`), ANY_VALUE(`email`), `name` FROM `users` GROUP BY `name`
이제 왜 사용을 ANY_VALUE
권장하지 않는지 묻습니다 .
MySQL은 그룹화 된 레코드의 값을 정확히 알지 못하기 때문에이 기능을 사용하여 레코드를 가져 오도록 요청합니다 (이 경우 이름이 John 인 첫 번째 레코드의 전자 메일을 가져 왔습니다).
나는 왜 당신이이 행동이 존재하기를 원하는지에 대한 아이디어를 내놓을 수 없습니다.
나를 이해하지 못하면 MySQL에서 그룹화가 어떻게 작동하는지 자세히 읽어보십시오. 매우 간단합니다.
그리고 마지막으로, 여기에 하나 더 간단하지만 유효한 쿼리가 있습니다.
사용 가능한 연령에 따라 총 사용자 수를 쿼리하려면이 쿼리를 작성하십시오.
SELECT `age`, COUNT(`age`) FROM `users` GROUP BY `age`;
MySQL 규칙에 따라 완전히 유효합니다.
등등.
문제가 정확히 무엇인지 이해하고 해결책을 적어 두는 것이 중요합니다.
나는 laravel homestead (0.5.0, Laravel 5.3, mysql 5.7.12)를 사용하고 있습니다.
/etc/mysql/my.cnf
반영 하도록 편집 을 명시 적으로 설정 한 후에도 :
[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
여전히 오류가 발생했습니다.
나는 변경했습니다 config/database.php
에서 true
에 false
:
'mysql' => [
'strict' => false, //behave like 5.6
//'strict' => true //behave like 5.7
],
더 읽을 거리 :
https://laracasts.com/discuss/channels/servers/set-set-sql-mode-on-homestead https://mattstauffer.co/blog/strict-mode-and-other-mysql-customizations-in-laravel -5-2
wamp 3.0.6 또는 안정 2.5 이외의 상위 버전을 사용하는 경우이 문제가 발생할 수 있습니다. 먼저 sql 문제입니다. 그에 따라 필드 이름을 지정해야합니다. 그러나 다른 방법으로 해결할 수 있습니다. wamp의 녹색 아이콘을 클릭하십시오. mysql-> mysql 설정-> sql_mode-> 없음. 또는 콘솔에서 기본값을 변경할 수 있습니다.
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';
파일에 줄 추가 (아래 설명) : /etc/mysql/my.cnf
[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.7.18-0ubuntu0.16.04.1-(우분투)
맥의 경우 :
1. 기본 my-default.cnf를 /etc/my.cnf에 복사하십시오.
sudo cp $(brew --prefix mysql)/support-files/my-default.cnf /etc/my.cnf
2. 좋아하는 편집기를 사용하여 my.cnf에서 sql_mode를 변경하고 이것을 설정하십시오.
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
3. MySQL 서버를 다시 시작하십시오.
mysql.server restart
localhost / wampserver 3의 경우이 오류를 제거하기 위해 sql-mode = user_mode를 설정할 수 있습니다.
click on wamp icon -> MySql -> MySql Setting -> sql-mode -> user_mode
그런 다음 늪이나 아파치를 다시 시작하십시오.
이것이 전체 문제를 이해하는 데 도움이 된 것입니다.
- https://stackoverflow.com/a/20074634/1066234
- https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
다음은 문제가되는 쿼리의 다른 예입니다.
문제가있는 :
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 = #
이것을 끝에 추가하여 해결했습니다.
GROUP BY timestamp, userid, cookieid, questionid, answerid, elapsed, ipaddress
참고 : PHP의 오류 메시지를 참조하십시오. 문제의 위치를 알려줍니다.
예:
MySQL 쿼리 오류 1140 : GROUP BY가없는 집계 된 쿼리에서 SELECT 목록의 식 # 4는 집계되지 않은 열 'db.gameplay.timestamp'를 포함합니다. sql_mode = only_full_group_by와 호환되지 않음-쿼리 : 시도로 SELECT COUNT (*), 경과로 표시된 SUM (elapsed), userid, timestamp, questionid, answerid, SUM (correct)로 정확, 경과, ipaddress FROM gameplay WHERE timestamp> = DATE_SUB (NOW (), INTERVAL 1 DAY) AND userid = 1
이 경우 GROUP BY에서 식 # 4 가 누락되었습니다.
당신은 추가 할 수 있습니다 unique index
합니다 group_id
; 당신은 그것이 group_id
독특 하다고 확신한다면 .
쿼리를 수정하지 않고도 사례를 해결할 수 있습니다 .
답변이 늦었지만 답변에 아직 언급되지 않았습니다. 사용 가능한 이미 포괄적 인 답변을 완료해야 할 수도 있습니다. 적어도 필드가 너무 많은 테이블을 분할해야 할 때 적어도 내 경우를 해결했습니다.
doctrine query builder를 사용하여 Symfony 에이 오류가 있고이 오류가 orderBy 에 의해 발생한 경우 :
select
원하는 열에 주의를 기울이고 대신에 groupBy
사용하십시오 .addGroupBy
groupBy
$query = $this->createQueryBuilder('smth')->addGroupBy('smth.mycolumn');
Symfony3에서 작동 -
정확한 SQL을 사용하지 않은 것에 대한 사과
이 쿼리를 사용하여 Mysql 경고를 극복했습니다.
SELECT count(*) AS cnt, `regions_id`
FROM regionables
WHERE `regionable_id` = '115' OR `regionable_id` = '714'
GROUP BY `regions_id`
HAVING cnt > 1
나를위한 열쇠에 주목
count(*) AS cnt
'Programming' 카테고리의 다른 글
UIImage의 크기를 조정하는 가장 간단한 방법은 무엇입니까? (0) | 2020.02.25 |
---|---|
콘솔의 텍스트 진행률 표시 줄 (0) | 2020.02.25 |
NUnit 대 MbUnit 대 MSTest 대 xUnit.net (0) | 2020.02.25 |
기존 Git 저장소를 SVN으로 푸시 (0) | 2020.02.25 |
jQuery로 텍스트 노드를 어떻게 선택합니까? (0) | 2020.02.25 |