1

我需要一些有关 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

结果如下:

在此处输入图像描述

但是,如果我将另一个表添加到“来自”,可以说:utilizador 表(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 子句中使用它)这一事实非常重要。有人可以给我一些帮助吗?

亲切的问候

4

4 回答 4

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
于 2013-09-26T16:20:57.750 回答
1

结果没有改变,只是每个结果被重复的次数等于新表中的行数。原因是您在 where 子句中添加了没有任何连接的新表,因此您有一个交叉连接。

于 2013-09-26T16:19:40.150 回答
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,或者更好地说是一个笛卡尔积。

于 2013-09-26T16:20:37.140 回答
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

但是你说的都是对的。问题是它多次计算同一件事。

谢谢大家

亲切的问候

于 2013-09-26T18:13:51.227 回答