В предложении выбора есть поле, которого нет в группе: gid
. montant_ht_actualise_echeance
Это очень опасная функция MySQL и MariaDB, которая может дать неожиданные результаты, как вы выяснили.
Другие базы данных отклонят ваш запрос, но, если ваш режим SQL не содержит «ONLY_FULL_GROUP_BY», MariaDB примет запрос и затем предоставит вам первое значение, с которым он столкнется при чтении.
Добавление индекса изменяет порядок получения записей заказов, поэтому вы получаете что-то другое. Фактически, даже добавление / обновление / удаление других записей может изменить результат группы, поскольку может измениться, в каком блоке находится запись.
Вы можете исправить свой запрос, добавив gid
. montant_ht_actualise_echeance
в оператор Group by.
В качестве альтернативы вы можете выбрать агрегированную функцию для вычисления суммы, max, first_value или last_value.
В ответ на комментарий:
GROUP BY означает «Для каждой комбинации этих полей сделайте одну запись». Поэтому, если у вас есть «GROUP BY year, month», вы получите одну запись для каждой комбинации года и месяца, которая находится в таблице.
Кроме того, вы помещаете здесь все значения, которые, как вы знаете, имеют уникальное значение внутри групп. Это означает, что «четверть» должна идти сюда, поскольку месяц всегда имеет уникальное значение для квартала. «Название компании» также должно указываться там, если для всех записей есть только одно значение.
Для всех других полей вам нужно указать базе данных, как обрабатывать найденные множественные значения. Числовые поля просты: вы можете SUM (цена) или COUNT (идентификатор) и т. Д. Для текстовых полей вам нужно выбрать: MIN, MAX (в алфавитном порядке), FIRST_VALUE (это то, что у вас есть сейчас, неявно) или даже GROUP_CONCAT для добавления всех значений в одну строку.
Чтобы получить значение gid.montant_ht_actualise_echeance, связанного с последним (макс.) gid
. date_quittancement_echeance
, вам необходимо сначала определить записи с максимальной датой и использовать их для выбора нужных значений из таблицы.
В MySQL / MariaDB это чаще всего делается путем самостоятельного присоединения к таблице. Если в таблице есть столбец unqiue key / id, используйте его для объединения, но если нет, то это будет примерно так:
SELECT `gid`.`num_version_contrat` AS `num_version_contrat`,
`gid`.`date_quittancement_echeance` AS `max_date_quittancement_echeance`,
`gid`.`montant_ht_actualise_echeance` AS `dernier_montant`
FROM `gid`
INNER JOIN
(
SELECT `gid`.`num_version_contrat` AS `num_version_contrat`,
MAX(`gid`.`date_quittancement_echeance`) AS max_date
FROM `gid`
GROUP BY `gid`.`num_version_contrat`
) last_dates
ON `gid`.`num_version_contrat` = `last_dates`.`num_version_contrat`
AND `gid`.`date_quittancement_echeance` = `last_dates`.`max_date`
WHERE `gid`.num_version_contrat = "100313 V.0"
ORDER BY `gid`.`num_version_contrat`
Первая часть выбирает поля, которые вы хотите. Вторая часть находит только max_dates для версии контракта, а INNER JOIN хранит только записи, найденные в обеих, удаляя все записи, которые не имеют max_date.
Предполагается, что предложение WHERE предназначено только для тестирования и будет удалено позже.
В противном случае вся группа не имеет смысла.