0

我有这些表GenreSongs. 顺便说一句,显然存在多对多的关系,因为一种流派可以(显然)有很多歌曲,而一首歌可能属于多种流派(比如说有一首歌xyz,它属于说唱,也可以属于嘻哈)。我有这个表GenreSongs作为多对多关系映射这两个,因为它包含GenreIDSongID列。因此,我应该这样做,在此Genre表中添加一个名为的列,该列SongsCount将包含该类型的歌曲数量。我可以更改表以添加一列,还可以创建一个查询来计算歌曲的数量,

SELECT GenreID, Count(SongID) FROM GenreSongs GROUP BY GenreID

现在,这给了我们所需的内容,即每种流派的歌曲数量,但我如何使用此查询来更新我创建的列 ( SongsCount)。一种方法是运行此查询并查看结果,然后手动更新该列,但我相信每个人都会同意这不是一种编程方式。我开始认为我需要创建一个带有子查询的查询,该查询GenreID将从外部查询中获取值,然后从内部查询(相关查询)中计算其值,但我什么也做不了。有人可以帮我做这个吗?

4

2 回答 2

0

制作一个名为 SongsCount 的表显然是糟糕的设计(冗余数据和更新开销)。而是将此查询用于单个结果:

SELECT ID, ..., (SELECT Count(*) FROM GenreSongs WHERE GenreID = X) AS SongsCount FROM Genre WHERE ID = X

这适用于多个结果(效率更高):

SELECT ID, ..., SongsCount FROM (SELECT GenreID, Count(*) AS SongsCount FROM GenreSongs GROUP BY GenreID) AS sub RIGHT JOIN Genre AS g ON sub.GenreID = g.ID
于 2012-06-03T20:44:08.633 回答
0

如何解决这个问题取决于数据的大小和更新频率。这里有一些场景。

如果您的歌曲更新非常频繁并且您的表格非常大,那么您可能希望在 Genre 中有一个包含计数的列,并使用 Songs 表上的触发器更新该列。

或者,您可以在 Genre 上的 GenreSong 表上建立索引。然后是以下查询:

select count(*)
from GenreSong gs
where genre = <whatever>

应该跑得很快。

如果您的歌曲不经常更新或成批更新(比如每晚或每周),那么您可以将歌曲计数更新为批次的一部分。您的查询可能如下所示:

update Genre
    set SongCnt = cnt
    from (select Genre, count(*) as cnt from GenreCount gc group by Genre) gc
    where Genre.genre = gc.Genre

还有一种可能性是您根本不需要存储该值。您可以将其作为动态计算的视图/查询的一部分。

关系数据库非常灵活,而且做事的方式通常不止一种。正确的方法在很大程度上取决于您要完成的工作。

于 2012-06-03T20:50:51.527 回答