定义一个计算列引用另一张表

6
我有两个数据库表,Team (ID, NAME, CITY, BOSS, TOTALPLAYER) 和 Player (ID, NAME, TEAMID, AGE),两个表之间的关系是一对多,一个团队可以有许多球员。
我想知道是否有一种方法可以在Team表中定义一个TOTALPLAYER列为计算列?
例如,如果有10个球员的TEAMID为1,则具有ID为1的行在Team表中将具有值为10的TOTALPLAYER列。如果我添加一个球员,TOTALPLAYER列的值增加到11,我不需要明确地指定它的值,让它由数据库生成。有人知道如何实现吗?
顺便说一下,数据库是SQL Server 2008 R2。

在查询时计算值有什么问题吗? - Andriy M
2个回答

9

是的,您可以这样做 - 您需要一个计算团队球员数量的函数,并在计算列中使用它:

CREATE FUNCTION dbo.CountPlayers (@TeamID INT)
RETURNS INT 
AS BEGIN
    DECLARE @PlayerCount INT

    SELECT @PlayerCount = COUNT(*) FROM dbo.Player WHERE TeamID = @TeamID

    RETURN @PlayerCount
END

然后定义您的计算列:

ALTER TABLE dbo.Team
ADD TotalPlayers AS dbo.CountPlayers(ID) 

现在,如果您选择了某个团队,该函数将被调用每次选中一个团队。该值不会保存在Team表中 - 每次从Team表中选择时都会即时计算。
由于它的值没有被保存,所以问题实际上是:它需要成为表上的计算列吗,还是只要在需要时使用存储的函数来计算球员数量就可以了?

2
@HeroIverson3:是的 - 它将在包括该列的表的每个SELECT上执行(包括每个SELECT * FROM Team)。 - marc_s
1
@HeroIverson3:要实现仅在某些内容更改时进行更新,您需要在“Player”表上设置触发器。但这总是存在不正常工作的风险 - 在这种情况下,我可能会在需要时使用函数(或等效子查询)计算玩家数量。 - marc_s
1
@HeroIverson3:同意。如果在“团队”中有一个静态可更新的TotalPlayers列,您必须确保为了安全起见,该列永远不会被任何显式的UPDATE操作所触及,除非是在触发器中进行(并且为了确保初始值为0,您可能需要指定一个DEFAULT约束,并且为了安全起见,在您的INSERT语句中始终省略该列)。 - Andriy M
1
@HeroIverson3:除非它是一个巨大的数据库,我会选择使用动态计算值。在表中使用像marc_s答案中那样的函数静态计算列可能有效,但如果表相当大,我只会使用这种方法。否则,我会在我的查询中计算该值。妥协解决方案可能是基于类似于laser_dude的查询定义视图。 - Andriy M
alter语句中的ID是来自于players表还是team表? - Wairimu Murigi
显示剩余6条评论

2

您不必在表中存储总数 - 当您进行查询时,可以计算它,例如:

SELECT teams.*, COUNT(players.id) AS num_players
FROM teams LEFT JOIN  players ON teams.id = players.team_id
GROUP BY teams.id;

这将在查询中创建一个名为"num_players"的附加列,如果有的话,将计算每个团队上的球员数量。


2
基本上是的,但这在SQL Server中无法编译,因为GROUP BY列列表必须包括SELECT子句中引用的所有非聚合列。 - Andriy M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接