【问题标题】:How to sum a multiple count from multiple tables如何对多个表中的多个计数求和
【发布时间】:2013-10-11 15:24:32
【问题描述】:

希望有人可以帮助我..

对于我的忠诚度计划,我会计算添加的歌曲数量、添加的课程数量、课程和歌曲的 cmets 数量等等。

对于名人堂,我想对具有最高声誉的成员进行查看。并在头像下方添加声望。

为此,我想总结一下: TOTAL = totalsongs + totallesson + totalsongcmets + totallessoncmets

我的表格如下所示:

海报

poster_id| username | 
---------|----------|
1        | lisa
2        | john
3        | ben

课程

lesson_id| title    | poster_id
---------|----------|----------
1        | lesson1  | 1
2        | lesson2  | 1
3        | lesson3  | 2
4        | lesson4  | 3
5        | lesson5  | 1
6        | lesson7  | 2

歌曲

song_id  | title    | poster_id
---------|----------|----------
1        | song 1   | 1
2        | song 2   | 1
3        | song 3   | 2

歌曲评论

com_id   | song_id  | poster_id | comment
---------|----------|-----------|--------
1        | 1        | 1         | This comment1
2        | 2        | 1         | This comment2
3        | 3        | 2         | This comment3

课程评论

com_id   | lesson_id| poster_id | comment
---------|----------|-----------|--------
1        | 1        | 1         | This comment1
2        | 2        | 1         | This comment2
3        | 3        | 2         | This comment3

请帮忙设置mysql查询

    SELECT poster.gebruikersnaam 
    SUM(
        (SELECT COUNT(*) FROM song) AS totalsongs +
        (SELECT COUNT(*) FROM lesson AS totallesson + 
        (SELECT COUNT(*) FROM songcomment AS totalsongcomments +
        (SELECT COUNT(*) FROM lessoncomment AS totallessoncomments +
        )
    FROM song
    INNER JOIN poster ON poster.poster_id = song.song_poster_id
    WHERE song.song_poster_id !=  '0'
    GROUP BY poster.poster_id
    ORDER BY TOTAL
    LIMIT 0 , 250

这没关系,但是.. 仍然必须按总和排序:)

SELECT P.poster_id,
  (SELECT COUNT(*) FROM song WHERE P.poster_id = song.song_poster_id) AS SongCount,
  (SELECT COUNT(*) FROM lesson WHERE P.poster_id = lesson.lesson_poster_id) AS LessonCount,
  (SELECT COUNT(*) FROM commentaar WHERE P.poster_id = commentaar.poster_id) AS SongCommCount,
  (SELECT COUNT(*) FROM lesson_comment WHERE P.poster_id = lesson_comment.lesson_comment_poster_id) AS LessonCommCount
FROM poster AS P
LIMIT 0, 50

编辑 2

    SELECT PM.poster_id , PM.SongCount , PM.LessonCount, PM.SongCommCount, PM.LessonCommCount, (PM.SongCount + PM.LessonCount + PM.SongCommCount + PM.LessonCommCount) AS TotalCount 
FROM (
  SELECT P.poster_id, 
    (SELECT COUNT(*) FROM song WHERE P.poster_id = song.song_poster_id) AS SongCount, 
    (SELECT COUNT(*) FROM lesson WHERE P.poster_id = lesson.lesson_poster_id) AS LessonCount, 
    (SELECT COUNT(*) FROM commentaar WHERE P.poster_id = commentaar.poster_id) AS SongCommCount, 
    (SELECT COUNT(*) FROM lesson_comment WHERE P.poster_id = lesson_comment.lesson_comment_poster_id) AS LessonCommCount 
  FROM poster AS P 
  LIMIT 0, 50
) AS PM
ORDER BY (PM.SongCount + PM.LessonCount + PM.SongCommCount + PM.LessonCommCount) DESC

编辑 3

    SELECT poster_id, 
       songCount, lessonCount, songCommentCount, lessonCommentCount,
       songCount + lessonCount + songCommentCount + lessonCommentCount as totalRank
FROM(SELECT poster.poster_id, 
            COALESCE(song.count, 0) as songCount,
            COALESCE(lesson.count, 0) as lessonCount,
            COALESCE(commentaar.count, 0) as songCommentCount,
            COALESCE(lesson_comment.count, 0) as lessonCommentCount
     FROM poster
     LEFT JOIN (SELECT song_poster_id, COUNT(*) as count
                FROM song
                GROUP BY song_poster_id) song
            ON song.song_poster_id = poster.poster_id  
     LEFT JOIN (SELECT lesson_poster_id, COUNT(*) as count
                FROM lesson
                GROUP BY lesson_poster_id) lesson
            ON lesson.lesson_poster_id = poster.poster_id
     LEFT JOIN (SELECT poster_id, COUNT(*) as count
                FROM commentaar
                GROUP BY poster_id) commentaar
            ON commentaar.poster_id = poster.poster_id
     LEFT JOIN (SELECT lesson_comment_poster_id, COUNT(*) as count
                FROM lesson_comment
                GROUP BY lesson_comment_poster_id) lesson_comment
            ON lesson_comment.lesson_comment_poster_id = poster.poster_id) Total
ORDER BY totalRank DESC
LIMIT 0, 50

【问题讨论】:

    标签: mysql sql count sum


    【解决方案1】:

    这是SQL Fiddle,表明以下查询确实有效。如您所见,我正在创建表格并使用您在问题中拥有的数据填充它们。然后我正在执行以下查询来收集您需要的数据。我确实验证了计数并且它们计算正确。

    SELECT PM.*, 
      (
        PM.SongCount + PM.LessonCount + 
        PM.SongCommCount + PM.LessonCommCount
      ) AS TotalCount 
    FROM (
      SELECT P.poster_id, 
        (
          SELECT COUNT(poster_id) 
          FROM song S 
          WHERE P.poster_id = S.poster_id
        ) AS SongCount, 
        (
          SELECT COUNT(poster_id) 
          FROM lesson L 
          WHERE P.poster_id = L.poster_id
        ) AS LessonCount, 
        (
          SELECT COUNT(poster_id) 
          FROM SongComment SC 
          WHERE P.poster_id = SC.poster_id
        ) AS SongCommCount, 
        (
          SELECT COUNT(poster_id) 
          FROM LessonComment LC 
          WHERE P.poster_id = LC.poster_id
        ) AS LessonCommCount 
      FROM poster AS P 
      LIMIT 0, 50
    ) AS PM
    ORDER BY 
      (
        PM.SongCount + PM.LessonCount + 
        PM.SongCommCount + PM.LessonCommCount
      ) DESC
    

    【讨论】:

    • 我添加了 LIMIT 0,50 但此查询需要:273.4195 秒才能运行!?它还为用户的所有 TotalCounts 返回 0。希望你知道出了什么问题?
    • 单独尝试 Count() 子查询,看看你是否得到一个非 0 的值
    • 这个查询并不奇怪,因为我在寻找前 50 名最佳海报。但是这样说 WHERE P.poster_id = song.poster_id 这不是 P.poster_id ON song.poster_id
    • 不,没关系。您必须将子查询链接到主查询。您可以使用 WHERE 语句来执行此操作。
    • 尝试我添加的编辑,看看它是否会运行得更快并产生任何结果。
    【解决方案2】:

    除了@Linger 的回答,这是另一种常用的方法:

    SELECT poster_id, 
           songCount, lessonCount, songCommentCount, lessonCommentCount,
           songCount + lessonCount + songCommentCount + lessonCommentCount as totalRank
    FROM(SELECT Poster.poster_id, 
                COALESCE(Song.count, 0) as songCount,
                COALESCE(Lesson.count, 0) as lessonCount,
                COALESCE(SongComment.count, 0) as songCommentCount,
                COALESCE(LessonComment.count, 0) as lessonCommentCount
         FROM Poster
         LEFT JOIN (SELECT poster_id, COUNT(*) as count
                    FROM Song
                    GROUP BY poster_id) Song
                ON Song.poster_id = Poster.poster_id  
         LEFT JOIN (SELECT poster_id, COUNT(*) as count
                    FROM Lesson
                    GROUP BY poster_id) Lesson
                ON Lesson.poster_id = Poster.poster_id
         LEFT JOIN (SELECT poster_id, COUNT(*) as count
                    FROM SongComment
                    GROUP BY poster_id) SongComment
                ON SongComment.poster_id = Poster.poster_id
         LEFT JOIN (SELECT poster_id, COUNT(*) as count
                    FROM LessonComment
                    GROUP BY poster_id) LessonComment
                ON LessonComment.poster_id = Poster.poster_id) Total
    ORDER BY totalRank DESC
    LIMIT 0, 50
    

    (有一个工作的SQL Fiddle example - 感谢@Linger 的设置)
    我对 mySQL 知之甚少,不知道这是否会更适合您的情况。请注意,LIMIT 子句应该不是问题,因为无论如何您都希望它们被订购。此外,如果您在每个“子”表中没有超过 poster_id 的索引,您可能会想要它们...

    【讨论】:

    • 查询确实按预期工作,但是:查询执行时间 25.2329 秒。但我已经用我的特定表格信息重写了它。检查我的编辑 3。我的桌子不使用大写字母,只是海报,或评论 (=songcmets) 和 lessen_cmets。希望我们可以修复获取时间:)
    • @linger,我什至没有检查 Fiddle 示例,这对我来说是已知的,但谢谢!我可以用它来解决我可能遇到的任何其他问题。 :)(可能要先在这里注册..)
    • ...如果您的问题没有列出“正确”的列名,那是您的问题,不是我的问题。特别是由于有些人必须匿名他们的表格/列,因此预计提问者会根据需要翻译答案。此外,除非您使用特定选项(通常不建议这样做),否则 SQL 实际上是不区分大小写的;人们通常使用某些套管样式来帮助区分事物。还有什么需要的吗?
    • 我不理解查询我尝试了所有类型的选项但没有歌曲评论计数需要 6 秒才能加载但需要 24 秒。什么可能导致这个加载时间(这个歌曲评论表只有 5000 行,歌曲是 10000 行,海报是 50.000 行。已经谢谢了。
    • 太多可能性 - 缺少索引、机器不足、DBA 将表卡在不同的物理位置等。如果您有特定的性能问题,请提出问题。
    猜你喜欢
    • 2017-09-28
    • 2021-11-29
    • 1970-01-01
    • 2015-06-24
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 2013-08-05
    • 1970-01-01
    相关资源
    最近更新 更多