使用另一张表中的数据创建计算列

16

我有一个 SQL Server 2008 R2 数据库。这个数据库有两个表叫做 Pictures 和 PictureUse。

Picture 表有以下列:

Id (int)   
PictureName (nvarchar(max)) 
CreateDate (datetime )  

PictureUse表包含以下列:

Id (int) 
Pictureid (int) 
CreateDate (datetime )  

我需要在Picture表中创建一个计算列,以告诉我这张图片被点击了多少次。有什么帮助吗?

5个回答

31

你可以为此创建一个用户定义的函数:

CREATE FUNCTION dbo.CountUses(@pictureId INT)
RETURNS INT
AS
  BEGIN
      RETURN
        (SELECT Count(id)
         FROM   PictureUse
         WHERE  PictureId = @PictureId)
  END 

可以像这样添加计算列:

ALTER TABLE dbo.Picture
ADD NofUses AS dbo.CountUses(Id)

不过,我更倾向于这样的观点:

CREATE VIEW PictureView
AS
  SELECT Picture.Id,
         PictureName,
         Picture.CreateDate,
         Count(PictureUse.Id) NofUses
  FROM   Picture
         JOIN PictureUse
           ON Picture.Id = PictureUse.PictureId
  GROUP  BY Picture.Id,
            PictureName,
            Picture.CreateDate 

1
@Smartboy,“CREATE FUNCTION dbo.CountUses(INT @pictureId)” 应该改为 “CREATE FUNCTION dbo.CountUses(@pictureId INT)”。此外,函数缺少“BEGIN .. END”和“RETURN”。 - Martin Smith
1
@MartinSmith 你能修复整个函数吗?它仍然报错。 - Smartboy
@Smartboy - 不知道。在我看来,它应该可以工作。这些图片在“PictureUse”中是否有多个条目? - Martin Smith
是的,PictureUse 已经有将近 90,000 条记录了,我现在发现有些图片的 PictureUse 只有 35 或 38 行... - Smartboy
1
请检查您的GROUP BY - 您是按照Picture.CreateDate还是PictureUse.CreateDate进行分组? - jeroenh
显示剩余5条评论

11

计算列只能引用同一张表中的其他列。您可以(根据jeroenh的答案)使用UDF,但该列不会被存储或索引,因此每次访问行时都必须重新计算。

如果您只是想获取PictureUse中行数的计数,可以创建一个包含此信息的索引视图:

CREATE VIEW dbo.PictureStats
WITH SCHEMABINDING
AS
    SELECT PictureID,COUNT_BIG(*) as Cnt from dbo.PictureUse
GO
CREATE UNIQUE CLUSTERED INDEX IC_PictureStats on dbo.PictureStats (PictureID)

在幕后,SQL Server 将有效地创建一个包含此视图结果的表格,并且每次对 PictureUse 的插入、更新或删除都会自动维护这个结果表。


+1 当涉及到读取时,这比UDF要好得多,但一个大的警告是由于计数行上的锁定,它会序列化写入。 - Remus Rusanu

0

你不需要将计算列添加到表中,因为在更新后,如果原始表数据发生更改,则数据会变得不一致,你可以随时使用此选择语句来获取列计数,或将其创建为视图。

select p.id,count(*) as count 
from Picture P
join PictureUse  U
on p.id=u.Pictureid 
group by p.id

-1

这将会起作用

SELECT  P.id
        ,P.PictureName 
        ,COUNT(P.id) as [Count] 
        FROM Picture P
        INNER JOIN PictureUse PU 
        ON P.id=PU.Pictureid 
        GROUP BY P.id,P.PictureName 

-2

试一下这个

select count(distict pictureid) from pictureuse 
 inner join picture on picture.id=pictureuse.pictureid

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