MySQL Различные результаты из одного и того же запроса / данных

У меня есть два сервера под управлением MySQL. Оба на окнах. Один из них - мой локальный компьютер (Windows 7, MySQL 5.6.25, 32-битный), а другой - мой рабочий веб-сервер (Windows 2012, MySQL 5.7.11-log, 64-битный (это то, что мне показывали переменные).

Данные идентичны между ними. Я скопировал данные из Windows 7 (используя MySQL Workbench) и восстановил их на компьютере 2012 года.

Я выполняю запрос на обеих машинах, но получаю разные результаты. У меня есть две таблицы, проекты и заметки проектов с отношением 1:m между ними, связанные с projects.id и projectsnotes.idProject. Каждая заметка отмечена датой (dComment). Цель запроса - получить информацию о проекте и только последний комментарий.

Вот запрос:

select space(1) as cAction,
    p.id,
    p.iNum,
    p.cStatus,
    p.cName,
    p.cDesc,
    ifnull(pl.cNickName, 'UNASSIGNED') as cProjectLeader,
    IFNULL(concat (
            date_format(pn.dComment, '%Y-%m-%d'),
            ': ',
            pn.cComment
            ), '') as cComment,
    date_format(p.dRequested, '%Y-%m-%d') as dRequested,
    date_format(p.dRequired, '%Y-%m-%d') as dRequired,
    format(p.nPercentComplete, 2) as nPercentComplete,
    p.tLastUpdated,
    p.bCompleted,
    p.idProjectLeader
from projects p
left outer join projectleaders pl on p.idProjectLeader = pl.id
left outer join (
    select idProject,
        dComment,
        cComment
    from projectnotes
    order by dComment desc,
        tLastUpdated desc
    ) pn on p.id = pn.idProject
where p.cInstallCode = 'ITM'
    and cStatus in ('Pending', 'Active', 'On Hold', 'Completed', 'Cancelled')
    and bCompleted = 0
group by iNum
order by iNum;

Теперь вот странная часть. Когда я запускаю это на своем компьютере с Windows 7, я получаю правильное значение для cComment. В частности:

2017-03-28: текст из заметки заменить

Это последняя заметка. Когда я запускаю его на сервере 2012 года:

2016-05-17: текст этой заметки заменен

Если я запускаю один подзапрос на сервере 2012, я получаю правильные значения (а именно, список всех заметок в обратном порядке.

О, и эта заметка не является ни первой, ни последней в заметках к этому проекту.

Так что мне честно интересно, что происходит. Любые мысли по этому поводу будет принята с благодарностью.

Заранее спасибо.

2 ответа

Решение

Это ожидаемое поведение.

select ...
from projects p
left outer join projectleaders pl on p.idProjectLeader = pl.id
left outer join (...) pn on p.id = pn.idProject
where ...
group by iNum
order by iNum;

Из-за специфической обработки MySQL для GROUP BY он не будет сообщать об ошибке в этом запросе. Однако вы должны иметь в виду, что, поскольку вы не используете агрегаты, а GROUP BY удалит много строк, строки, которые хранятся в окончательном наборе результатов, определяются довольно неясными критериями...

Например:

SELECT a,b FROM t GROUP BY a

Какой б будет возвращен? В некоторых версиях MySQL это будет первое значение b, найденное в таблице t. Если таблица t упорядочена определенным образом, это можно использовать. Но я бы определенно не доверял этому поведению, чтобы оно оставалось неизменным между версиями... Кроме того, помните, что MySQL может свободно изменять порядок соединения...

ХОРОШО. Я думаю, что у меня есть решение этого. Вместо того чтобы делать это с помощью соединения, я написал функцию, которая возвращала нужное мне значение следующим образом:

DROP FUNCTION if exists f_lastprojectnote;
DELIMITER $$

CREATE FUNCTION f_lastprojectnote(tidProject varchar(36))
RETURNS varchar(1000) DETERMINISTIC
BEGIN
    DECLARE cRetVal VARCHAR(1000);

    SELECT concat(date_format(pn.dComment, '%Y-%m-%d'), ': ', pn.cComment) INTO cRetVal
      FROM projectnotes pn
     WHERE idProject = tidProject
     ORDER BY dComment DESC, tLastUpdated DESC
     LIMIT 1;

    RETURN cRetVal;
END$$

DELIMITER ;

Оно работает...

Другие вопросы по тегам