【问题标题】:MySQL Joining ProblemsMySQL 连接问题
【发布时间】:2010-09-23 08:23:25
【问题描述】:

以下查询对我来说返回了奇怪的结果:

SELECT
    `Statistics`.`StatisticID`,
    COUNT(`Votes`.`StatisticID`) AS `Score`,
    COUNT(`Views`.`StatisticID`) AS `Views`,
    COUNT(`Comments`.`StatisticID`) AS `Comments`
FROM `Statistics`
LEFT JOIN `Votes` ON `Votes`.`StatisticID` = `Statistics`.`StatisticID`
LEFT JOIN `Views` ON `Views`.`StatisticID` = `Statistics`.`StatisticID`
LEFT JOIN `Comments` ON `Comments`.`StatisticID` = `Statistics`.`StatisticID`
GROUP BY `Statistics`.`StatisticID`
LIMIT 0, 10

我正在对如下表结构进行查询:

(仅与Statistics.StatisticID = 8相关的数据)

投票

StatisticID
    8

观看次数

StatisticID
    8
    8

评论

StatisticID
    8
    8
    8
    8
    8

现在,如果我运行此查询,我会得到以下结果集:

StatisticID    Score    Views   Comments
     8           5        5        5

我知道 5 来自哪里 - 评论的数量 - 如果我把 cmets 语句去掉,这将有效。任何人都可以调试它,因为这超出了我的能力范围(我对 SQL 比较陌生)。

谢谢, 罗斯

【问题讨论】:

标签: mysql join


【解决方案1】:

当像这样加入时,您将复制数据的次数与您在其他表中找到的数学行一样多。这很好,如果每个表中只有 1 个对应的行。

在没有分组的情况下运行此查询,您将了解为什么在所有计数上都得到相同的结果。然而,我猜你会得到 10 作为每个字段的计数(1 * 2 * 5) 如果你想解决这个问题,你需要为每个计数调用一个子选择。

选择 s.`StatisticID`, (SELECT COUNT(*) FROM Votes WHERE Votes.StatisticID = s.StatisticID) 作为分数, (SELECT COUNT(*) FROM Views WHERE Views.StatisticID = s.StatisticID) 作为视图, (SELECT COUNT(*) FROM Comments WHERE Comments.StatisticID = s.StatisticID) 作为评论, FROM `Statistics` s 限制 0, 10

如果外部结果很大,则存在某些性能问题。您可以通过加入其中一个表来对其进行一些优化,但是我不确定查询解析器是否足够聪明,只能为每个分组项目运行 1 次。希望它会。否则,您可以将其拆分为不同的查询。

【讨论】:

  • 我不会担心性能问题 - 这个子查询解决方案将完美执行,不会执行任何虚假操作!
  • 我更想的是,如果外部结果有 1000 行,那么它还需要运行 3000 个子查询。在这种情况下,一次加入一个表并调用 3 次查询可能会更快。
  • 同意子查询的事情 - 如果有很多外部结果。但我想目前我们确实有限制 0、10。另外,您已经从选票中选择了两次,第三个 suybquery 应该来自 cmets
  • 嗯,我确实改变了它,不知何故我的编辑被还原了,或者是更新中的一个小故障。
  • 谢谢,如果您没有向我指出这一点,我就不会意识到性能问题 :)
【解决方案2】:

假设您在投票/视图/cmets 上有一个 id 字段或类似字段:

SELECT
    `Statistics`.`StatisticID`,
    COUNT(DISTINCT `Votes`.`VoteID`) AS `Score`,
    COUNT(DISTINCT `Views`.`ViewID`) AS `Views`,
    COUNT(DISTINCT `Comments`.`CommentID`) AS `Comments`
FROM `Statistics`
LEFT JOIN `Votes` ON `Votes`.`StatisticID` = `Statistics`.`StatisticID`
LEFT JOIN `Views` ON `Views`.`StatisticID` = `Statistics`.`StatisticID`
LEFT JOIN `Comments` ON `Comments`.`StatisticID` = `Statistics`.`StatisticID`
GROUP BY `Statistics`.`StatisticID`
LIMIT 0, 10

没有测试过,但认为它应该可以工作。 (我们必须使用不同的字段,因为 statisticID 在给定组中总是相同的......)

【讨论】:

  • 其实这是一个更好的解决方案。不知道您可以在计数中使用 DISTINCT,只是对其进行了测试,它可以工作。
猜你喜欢
  • 2011-02-16
  • 1970-01-01
  • 2011-05-17
  • 2015-09-19
  • 2018-01-08
  • 2013-06-13
  • 2020-03-13
相关资源
最近更新 更多