我需要一些MySQL的帮助。假设我有这个问题Q1:
Q1:
select cn.idConteudo, TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim)
from navegacaolog nl, conteudoNo cn
where nl.idConteudoNo = cn.idConteudoNo AND
TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim) > 120
结果如下:
但是如果我将另一个表添加到“from”,让我们说:utilizador table(Q2),结果非常不同,如下图所示:
Q2:
select cn.idConteudo, TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim)
from navegacaolog nl, conteudoNo cn, utilizador
where nl.idConteudoNo = cn.idConteudoNo AND
TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim) > 120
我不明白为什么,添加另一个表(不在where子句中使用它)的事实非常重要。有人可以给我一些帮助吗?
亲切的问候
答案 0 :(得分:4)
您尚未指定连接条件,因此您获得的是FULL CROSS JOIN,它为基表中的每个可能的行组合生成一行。
http://en.wikipedia.org/wiki/Join_(SQL)
我发现使用ANSI语法进行连接可以避免这种混淆。不要只使用FROM子句中的逗号...使用实际的JOIN子句...
select cn.idConteudo, TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim)
from navegacaolog nl
JOIN conteudoNo cn ON nl.idConteudoNo = cn.idConteudoNo
where TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim) > 120
答案 1 :(得分:1)
结果没有改变,只是每个结果重复的次数等于新表中的行数。 原因是你在where子句中添加了没有任何连接的新表,因此你有一个交叉连接。
答案 2 :(得分:1)
这是因为您没有意识到您正在使用非ansi SQL连接语法来投射笛卡尔积。
如果您之前有n个结果,那么添加x记录的新表将在逻辑上提供n * x个总结果。
使用ANSI语法更好地了解您的查询(例如https://stackoverflow.com/a/11180050/1291428以查看常见错误)
此
SELECT cn.idConteudom SUM(uta.pontuacao), SUM(TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim))
FROM navegacaolog nl
JOIN conteudoNo cn ON nl.idConteudoNo = cn.idConteudoNo AND
TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim) > 120
JOIN utilizador uta ON uta.idUtilizador = nl.idUtilizador
GROUP BY cn.idConteudo
是您的查询,已标准化。在没有连接条件的情况下加入表(utilizador
)意味着实现CROSS JOIN
,或者更好地说出笛卡尔积。
答案 3 :(得分:0)
完成。我真正想要的是这样的:
select Q1.idConteudo, Q2.PONTUACAO, Q1.TEMPO
from
(select cn.idConteudoNo AS idConteudoNo, cn.idConteudo AS idConteudo,sum(TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim)) AS TEMPO
from navegacaolog nl
JOIN conteudoNo cn
ON nl.idConteudoNo = cn.idConteudoNo
where TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim) > 120
group by cn.idConteudoNo) AS Q1
,
(select nl.idConteudoNo AS idConteudoNo, sum(uta.pontuacao) AS PONTUACAO
from navegacaolog nl
JOIN utilizadortesteavaliacao uta
ON nl.idUtilizador = uta.idUtilizador
where TIMESTAMPDIFF(SECOND, nl.dataInicio , nl.dataFim) > 120
group by nl.idConteudoNo
) AS Q2
WHERE
Q1.idConteudoNo = Q2.idConteudoNo
但你所说的都是正确的。问题是它数次计算的次数相同。
感谢所有
亲切的问候