==
тесты для ссылочного равенства (независимо от того, являются ли они одним и тем же объектом).
.equals()
тесты для равенства значений (независимо от того, являются ли они логически «равными»).
Objects.equals () проверяет наличие null
перед вызовом .equals()
, поэтому вам не нужно (доступно с JDK7, также доступным в Guava ).
String.contentEquals () сравнивает содержимое String
с содержимым любого CharSequence
(доступно с Java 1.5).
Следовательно, если вы хотите проверить, имеет ли две строки одно и то же значение, вы, вероятно, захотите использовать Objects.equals()
.
// These two have the same value
new String("test").equals("test") // --> true
// ... but they are not the same object
new String("test") == "test" // --> false
// ... neither are these
new String("test") == new String("test") // --> false
// ... but these are because literals are interned by
// the compiler and thus refer to the same object
"test" == "test" // --> true
// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true
// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true
Вы почти всегда хотите использовать Objects.equals()
. В редкой ситуации, когда вы знаете, что имеете дело с интернированными строками, вы можете использовать ==
.
Из JLS 3.10. 5. Строковые литералы :
Кроме того, строковый литерал всегда ссылается на тот же экземпляр класса
blockquote>String
. Это связано с тем, что строковые литералы, или, в более общем смысле, строки, которые являются значениями константных выражений ( §15.28 ), «интернированы», чтобы обмениваться уникальными экземплярами, используя методString.intern
.. Подобные примеры также можно найти в JLS 3.10.5-1 .
Я бы просто добавил group_id
к GROUP BY
.
Когда SELECT
столбца, который не является частью GROUP BY
, может быть несколько значений для этого столбца внутри групп, но в результатах будет только одно место для одного значения. Таким образом, для базы данных обычно должно быть сказано точно, как сделать эти несколько значений одним значением. Обычно это выполняется с помощью агрегатной функции, такой как COUNT()
, SUM()
, MAX()
и т. Д. Я обычно говорю , потому что большинство других популярных систем баз данных настаивают на этом. Однако в MySQL до версии 5.7 поведение по умолчанию было более прощающим, потому что оно не будет жаловаться, а затем произвольно выбирает любое значение ! Он также имеет функцию ANY_VALUE()
, которая может быть использована в качестве другого решения для этого вопроса, если вам действительно необходимо такое же поведение, как и раньше. Эта гибкость стоит дорого, потому что она недетерминирована, поэтому я бы не рекомендовал ее, если у вас нет веских оснований для ее использования. MySQL теперь по умолчанию устанавливает параметр only_full_group_by
по уважительным причинам, поэтому лучше всего привыкнуть к нему и выполнить ваши запросы.
Итак, почему мой простой ответ выше? Я сделал несколько предположений:
1) group_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
Я попытаюсь объяснить вам, что это за ошибка. Начиная с MySQL 5.7.5, опция ONLY_FULL_GROUP_BY
включена по умолчанию. Таким образом, согласно стандарту SQL92 и ранее:
не разрешает запросы, для которых список выбора, условие HAVING или список ORDER BY относятся к неагрегированным столбцам, которые не имеют ни имени в предложении GROUP BY, ни функционально зависимы от (однозначно определенных) столбцами GROUP BY
Итак, например:
SELECT * FROM `users` GROUP BY `name`;
После выполнения запроса вы получите сообщение об ошибке.
# 1055 - Выражение # 1 списка SELECT не находится в предложении GROUP BY и содержит неагрегированный столбец «testite». user.id ', который функционально не зависит от столбцов в предложении GROUP BY; это несовместимо с sql_mode = only_full_group_by
Почему? Поскольку MySQL точно не понимает, какие определенные значения из сгруппированных записей извлекаются, и это точка.
I.E. скажем, у вас есть эти записи в вашей таблице
users
:И вы выполните недопустимый запрос, показанный выше. И вы получите ошибку, показанную выше, потому что есть 3 записи с именем
John
, и это хорошо, но все они имеют разные значения полейВы можете исправить эту проблему, просто изменив свой запрос следующим образом:
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. И так далее. Важно понять, в чем проблема, и только потом записать решение.
GROUP BY DAY(created_date)
? Похоже, что он не работает, если добавлен DAY()
.
– eskimo
23 January 2018 в 00:29
вы можете отключить предупреждающее сообщение, как описано в других ответах, или вы можете понять, что происходит и исправить.
Начиная с MySQL 5.7.5, по умолчанию SQL-режим включает ONLY_FULL_GROUP_BY , что означает, что когда вы группируете строки и затем выбираете что-то из этих групп, вам нужно явно указать, из какой строки должен быть сделан этот выбор.
Mysql должен знать, какую строку в группе вы ищете, что дает вам две опции
group by rect.color, rect.value
, который может быть тем, что вы хотите в некоторых случаях, в противном случае возвращал бы повторяющиеся результаты с тем же цветом, который вам может не понадобиться AVG()
MIN()
MAX()
Полный список ANY_VALUE()
, если вы уверены, что все результаты внутри группы одинаковы. doc ONLY_FULL_GROUP_BY
по умолчанию
– azerafati
20 December 2016 в 08:54
Для localhost / wampserver 3 мы можем установить sql-mode = user_mode, чтобы удалить эту ошибку:
click on wamp icon -> MySql -> MySql Setting -> sql-mode -> user_mode
затем перезапустить wamp или apache
Это помогло мне понять всю проблему:
И в следующем примере проблемного запроса.
Проблемный:
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 выражение # 4 списка SELECT содержит неагрегированный столбец ' db.gameplay.timestamp '; это несовместимо с sql_mode = only_full_group_by - Query: SELECT COUNT (*) в качестве попыток, SUM (истек) как elapsedtotal, userid, timestamp, questionid, answerid, SUM (правильный) как правильный, истекший, ipaddress FROM gameplay WHERE timestamp> = DATE_SUB (NOW (), INTERVAL 1 DAY) И userid = 1
В этом случае выражение # 4 отсутствовало в GROUP BY.
Вы можете попытаться отключить настройку 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';
SELECT COUNT(*), t.* FROM my_table t GROUP BY col
, и у вас есть 20-50 столбцов, вы хотите потратить столько времени, добавив каждый столбца в группу?
– Shadowbob
8 June 2018 в 10:07
Если у вас есть эта ошибка с Symfony с помощью построителя запросов doctrine, и если эта ошибка вызвана 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
Используйте ANY_VALUE()
для ссылки на неагрегированный столбец.
Из MySQL 5.7 docs :
Вы можете добиться такого же эффекта без отключив
ONLY_FULL_GROUP_BY
, используяANY_VALUE()
, чтобы ссылаться на неагрегированный столбец....
Этот запрос может быть недействительным с включенным
ONLY_FULL_GROUP_BY
, поскольку столбец неагрегированных адресов в select list не указан в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;
Добавление строк (см. ниже) в файле: /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 - (Ubuntu)
Если вы используете wamp 3.0.6 или любую другую версию, отличную от версии 2.5, вы можете столкнуться с этой проблемой, во-первых, проблема связана с sql. вы должны указать поля соответственно. но есть другой способ, с помощью которого вы можете его решить. нажмите зеленую иконку wamp. mysql-> mysql settings-> sql_mode-> none. или с консоли вы можете изменить значения по умолчанию.
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';
show variables like '%sql_mode%';
в командной строке mysql, установить значение sql_mode
– Min Han
31 May 2018 в 04:30
Вы можете добавить unique index
в group_id
; если вы уверены, что group_id
уникален.
Он может решить ваш случай без изменения запроса.
Поздний ответ, но он еще не упоминался в ответах. Возможно, он должен заполнить уже исчерпывающие ответы. По крайней мере, это разрешило мой случай, когда мне пришлось разбивать таблицу со слишком большим количеством полей.
Если вы не хотите вносить какие-либо изменения в свой текущий запрос, выполните следующие шаги -
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. paginate
.
– Michael J. Calkins
26 August 2016 в 04:37
Я использую Laravel 5.3, mysql 5.7.12, на laravel homestead (0.5.0, я полагаю)
Даже после явной настройки редактирования /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- в-Laravel-5-2
Для mac:
1.Copy по умолчанию my-default.cnf to /etc/my.cnf
sudo cp $(brew --prefix mysql)/support-files/my-default.cnf /etc/my.cnf
2. Измените sql_mode в my.cnf, используя любимый редактор и установите его на этот
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.Restart MySQL.
mysql.server restart
GROUP BY
в моем запросе, но я получаю эту ошибку. – Haroon Khan 29 August 2017 в 05:01