Mysql 计算多个联接的更好方法

Mysql 计算多个联接的更好方法,mysql,sql,Mysql,Sql,我对教会管理网站的敬拜歌模块的架构如下所示: 歌曲-id、名称 song_图书-id、名称、可用 书与歌-歌与歌书之间的多对多关系,每首歌可以在多本书中有一个数字,如果教堂使用多本书,任何数字都可以 song_曲目-id、日期、领导者、服务-日期和服务的唯一约束 songs_led-id、track_id、song_id-特定跟踪日led的歌曲列表 下面的查询获取一个时间范围内播放的歌曲列表、图书名称和编号以及播放次数 “按计数”语句是 COUNT(`l`.`song_id`) 以前,但当一首

我对教会管理网站的敬拜歌模块的架构如下所示:

歌曲-id、名称

song_图书-id、名称、可用

书与歌-歌与歌书之间的多对多关系,每首歌可以在多本书中有一个数字,如果教堂使用多本书,任何数字都可以

song_曲目-id、日期、领导者、服务-日期和服务的唯一约束

songs_led-id、track_id、song_id-特定跟踪日led的歌曲列表

下面的查询获取一个时间范围内播放的歌曲列表、图书名称和编号以及播放次数

“按计数”语句是

COUNT(`l`.`song_id`)
以前,但当一首歌出现在多本书中时,它的数量增加了一倍,所以我除以一首歌出现在可用的书中的数量

SELECT `s`.`name`,
       `s`.`id`,
       `bs`.`number`,
       `b`.`name` AS `bname`,
       CEIL(COUNT(`l`.`song_id`)/
              (SELECT COUNT(songs.id)
               FROM songs
               LEFT JOIN books_songs ON books_songs.song_id = songs.id
               AND books_songs.book_id IN
                 (SELECT id
                  FROM song_books
                  WHERE available <> 0)
               WHERE songs.id = s.id)) AS `count`
FROM `songs` AS `s`
JOIN `songs_led` AS `l` ON (`l`.`song_id` = `s`.`id`)
JOIN `books_songs` AS `bs` ON (`bs`.`song_id` = `s`.`id`)
JOIN
  (SELECT *
   FROM song_books
   WHERE available <> 0
   ORDER BY name ASC) AS `b` ON (`bs`.`book_id` = `b`.`id`)
JOIN `song_tracks` AS `t` ON (`l`.`track_id` = `t`.`id`)
WHERE `t`.`date` >= '2013-10-29'
  AND `t`.`date` <= '2013-12-28'
GROUP BY `s`.`id`
ORDER BY `count` DESC,
         `s`.`name`,
         `b`.`name`

有更好的方法吗?我希望以后不要进入这种地狱。

如果每首歌都有自己的ID,即使它出现在多本书中,那么你也许可以使用

   COUNT(DISTINCT song_id)

避免重复计算出现在多本书中的内容

此查询是否为您提供了正确的计数?从歌曲曲目中选择count*,日期在哪里?和非常感谢。我是个白痴——我想知道为什么我完全没有意识到这一点?在本例中,我使用了DISTINCT l.id,因为我计算的是每首歌曲的引导次数;有时很难知道这一切是什么。