only_full_group_by не позволяет мне показывать таблицу так, как я хочу - PullRequest
0 голосов
/ 25 сентября 2019

У меня новый VPS-сервер с MySQL-сервером версии 5.7.27.В этом новом VPS я загрузил базу данных и некоторый код, который был у меня с моего предыдущего сервера, который имел и более старую версию сервера MySQL.

В версии MySQL для сервера 5.7.27 only_full_group_by включен по умолчанию.Проблема возникает, когда на новом сервере VPS я пытаюсь выполнить запрос, содержащий оператор GROUP BY, который раньше работал на моем старом сервере, но теперь на новом сервере я получаю следующее сообщение.

1055: Выражение №1 списка SELECT отсутствует в предложении GROUP BY и содержит неагрегированный столбец «ihrwpmmy_loyal.i.id», который функционально не зависит от столбцов в предложении GROUP BY;это несовместимо с sql_mode = only_full_group_by

Я знаю, что есть возможность удалить / отключить only_full_group_by , но вместо этого я хотел бы сделать все правильно и внести исправления в мой запрос.

Я читал и узнал, что добавление i.id к выражению GROUP BY снова покажет значения в таблице, но я на самом деле не хочу GROUP BY i.id Вместо этого я бы хотел использовать только GROUP BY i.loadNumber , но я был вынужден использовать GROUP BY i.id , чтобы устранить ошибку.Мне действительно нужно тоже GROUP BY i.loadNumber , потому что у меня есть дублированные номера загрузки, которые я не хочу показывать в таблице.

SELECT i.id AS ivoiceIDAOC,
        i.debtorId,
        i.loadNumber,
        i.amountUsd,
        i.sentDate,
        i.commissionStatus,
        i.paidDate,
        i.status,
        cp.amountUsd AS amountUsdCarriersPayments,
        i.amountUsd - SUM(cp.amountUsd) AS companyProfitUsd,
        ROUND((i.amountUsd - SUM(cp.amountUsd)) * 0.10, 2) AS salesRepProfitUsd,
        ROUND(((i.amountUsd - SUM(cp.amountUsd)) * 0.10) * 0.50, 2)  AS advanceOnCommissionUsd,
        l.id,
        l.clientName,
        l.repID
        FROM invoice i
        LEFT OUTER JOIN leads l ON i.debtorId = l.id
        INNER JOIN carriersPayments cp ON cp.loadNumber LIKE CONCAT('', i.loadNumber, '%')
        WHERE True
        ".$filter_AOC_date."
        ".$filter_AOC_salesRep."
        AND i.commissionStatus IS NULL
        GROUP BY
        i.id,
        i.loadNumber,
        cp.amountUsd
        ORDER BY i.id desc";

Вот так выглядит таблица.

Load #|Customer Name| Paid Date |Revenue| Cost |Co Profit|SR Profit | AOC  |
------+-------------+-----------+-------+------+--------------------+------+
1570  | Customer 1  | 2019-09-19| $100  |  $50 |   $50   |   $5     | $2.5 |
1565  | Customer 2  | 2019-09-17| $102  |  $50 |   $52   |   $5.2   | $2.6 |
1565  | Customer 2  | 2019-09-16| $104  |  $50 |   $54   |   $5.4   | $2.7 |
1566  | Customer 3  | 2019-09-13| $106  |  $50 |   $56   |   $5.6   | $2.8 |

Как видно из таблицы примеров, если я добавлю i.id к своему оператору GROUP BY, когда я буду вынужден, я получу номер загрузки 1565 дважды.
Я бы хотел видеть только разные номера загрузок.

Load #|Customer Name| Paid Date |Revenue| Cost |Co Profit|SR Profit | AOC  |
------+-------------+-----------+-------+------+--------------------+------+
1570  | Customer 1  | 2019-09-19| $100  |  $50 |   $50   |   $5     | $2.5 |
1565  | Customer 2  | 2019-09-17| $206  | $100 |   $106  |   $10.6  | $5.3 |
1566  | Customer 3  | 2019-09-13| $106  |  $50 |   $56   |   $5.6   | $2.8 |

1 Ответ

1 голос
/ 25 сентября 2019

Вы находитесь в выбранном столбце, не участвующем в функции агрегации и не упомянутом в группе; это не разрешено по умолчанию для самой последней версии mysql

Кроме того, вы также используете тот же столбец в select ив функции агрегации это довольно странно, что вы не можете использовать ни то, ни другое, кажется бессмысленным

в поисках кода, который вы можете реорганизовать в запросе, используя правильный подзапрос

select loadNumber, SUM(amountUsd) sum_usd, SUM(amountCad) sum_cad
from  carriersPayments
group by loadNumber 

пример:

"SELECT i.id AS ivoiceIDAOC,
        i.debtorId,
        i.loadNumber,
        i.amountUsd,
        i.amountCad,
        i.sentDate,
        i.commissionStatus,
        i.paidDate,
        i.status,
        cp.amountUsd AS amountUsdCarriersPayments,
        cp.amountCad AS amountCadCarriersPayments,

        i.amountUsd - sum_usd AS companyProfitUsd,
        i.amountCad - sum_cad AS companyProfitCad,

        ROUND((i.amountUsd - sum_usd) * 0.10, 2) AS salesRepProfitUsd,
        ROUND((i.amountCad - sum_cad) * 0.10, 2) AS salesRepProfitCad,

        ROUND(((i.amountUsd - sum_usd) * 0.10) * 0.50, 2)  AS advanceOnCommissionUsd,
        ROUND(((i.amountCad - sum_cad) * 0.10) * 0.50, 2)  AS advanceOnCommissionCad,

        l.id,
        l.clientName,
        l.repID
        FROM invoice i
        INNER JOIN carriersPayments cp ON cp.loadNumber LIKE CONCAT('', i.loadNumber, '%')
        INNER JOIN  (
          select loadNumber, SUM(amountUsd) sum_usd, SUM(amountCad) sum_cad
          from  carriersPayments
          group by loadNumber 
          ) t ON t.loadNumber LIKE CONCAT('', i.loadNumber, '%')
        LEFT OUTER JOIN leads l ON i.debtorId = l.id
        WHERE True
        ".$filter_AOC_date."
        ".$filter_AOC_salesRep."
        AND i.commissionStatus IS NULL
        ORDER BY i.id desc";    

и, наконец, вы не должны использовать php var в sql, это рискует для sqlinject .. во избежание этого вам следует взглянуть на драйвер вашей БД для подготовленного statememnt и связующего параметра.

...