相关查询以基于选择更新表

时间:2012-06-03 20:17:30

标签: sql many-to-many subquery

我有这些表GenreSongs。他们之间有很多甚至很多关系,因为一种类型可以(显然)有很多歌曲,一首歌可能属于很多类型(比如有一首歌xyz,它属于说唱,它也可以属于嘻哈)。我有这个表GenreSongs,它充当了这两个关系图,因为它包含GenreIDSongID列。所以,我应该这样做,在这个名为Genre的{​​{1}}表中添加一列,其中包含此类型的歌曲数量。我可以改变表来添加一个列,也可以创建一个可以给出歌曲计数的查询,

SongsCount

现在,这为我们提供了我们所需要的,每种类型的歌曲数量,但我如何使用此查询来更新我创建的列(SELECT GenreID, Count(SongID) FROM GenreSongs GROUP BY GenreID )。一种方法是运行此查询并查看结果,然后手动更新该列,但我相信每个人都会同意这不是一种编程方式。 我开始认为我需要使用子查询创建一个查询,该查询将从外部查询中获取SongsCount的值,然后从内部查询(相关查询)中计算其值,但我无法生成任何查询。任何人都可以帮我做这件事吗?

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

另一种可能性是您根本不需要存储该值。您可以将其作为即时执行计算的视图/查询的一部分。

关系数据库非常灵活,通常有多种方法可以做。正确的方法在很大程度上取决于你想要完成的事情。

相关问题