MySQL 相同 query/data 的不同结果
MySQL Different results from same query/data
我有两台服务器 运行ning MySQL。两者都在 windows。一个是我的本地机器(Windows 7,MySQL 5.6.25,32 位),另一个是我的生产网络服务器(Windows 2012,MySQL 5.7.11-log , 64 位(这就是 show variables 给我看的)。
两者数据相同。我从 windows 7 备份数据(使用 MySQL Workbench)并在 2012 机器上恢复它。
我在两台机器上运行查询,但得到不同的结果。我有两个表,projects 和 projectnotes,它们之间有 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: Text from note replace
这是最新的笔记。当我 运行 它在 2012 服务器上时:
2016-05-17: Text from this note replaced too
如果我 运行 单独在 2012 服务器上进行子查询,我会得到正确的值(即所有注释的倒序列表。
哦,这个笔记既不是这个项目的笔记中的第一个也不是最后一个。
所以我真的很想知道发生了什么。对此有任何想法将不胜感激。
提前致谢。
这是预期的行为。
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
返回哪个b?在某些 MySQL 版本中,这将是在 table t 中找到的第一个 b 值。如果 table 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 ;
有效...
我有两台服务器 运行ning MySQL。两者都在 windows。一个是我的本地机器(Windows 7,MySQL 5.6.25,32 位),另一个是我的生产网络服务器(Windows 2012,MySQL 5.7.11-log , 64 位(这就是 show variables 给我看的)。
两者数据相同。我从 windows 7 备份数据(使用 MySQL Workbench)并在 2012 机器上恢复它。
我在两台机器上运行查询,但得到不同的结果。我有两个表,projects 和 projectnotes,它们之间有 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: Text from note replace
这是最新的笔记。当我 运行 它在 2012 服务器上时:
2016-05-17: Text from this note replaced too
如果我 运行 单独在 2012 服务器上进行子查询,我会得到正确的值(即所有注释的倒序列表。
哦,这个笔记既不是这个项目的笔记中的第一个也不是最后一个。
所以我真的很想知道发生了什么。对此有任何想法将不胜感激。
提前致谢。
这是预期的行为。
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
返回哪个b?在某些 MySQL 版本中,这将是在 table t 中找到的第一个 b 值。如果 table 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 ;
有效...