16

I have a SQL Server 2008 R2 database. This database has two tables called Pictures and PictureUse.

Picture table has the following columns:

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

PictureUse table has the following columns :

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

I need to create a computed column in the Picture table which tells me that how many times this picture has been clicked.any help ?

0

5 Answers 5

31

You can create a user-defined function for that:

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

The computed column can then be added like this:

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

However, I would rather make a view for this:

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 
Sign up to request clarification or add additional context in comments.

10 Comments

i tried your answer but its giving error when i am creating function and Computed column
should i create a column first or a function ?
@Smartboy CREATE FUNCTION dbo.CountUses(INT @pictureId) should be CREATE FUNCTION dbo.CountUses(@pictureId INT). Also the function is missing BEGIN .. END and a RETURN
@MartinSmith Can you fix the whole function its still giving error
Check your GROUP BY - are use grouping by Picture.CreateDate or by PictureUse.CreateDate?
|
11

A computed column may only reference other columns in the same table. You could (as per jeroenh's answer) use a UDF, but the column won't be stored or be indexable and so it has to be recomputed every time the row is accessed.

You could create an indexed view that contains this information (if, as I suspect, it's just the count of rows from 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)

Behind the scenes, SQL Server will effectively create a table that contains the results of this view, and every insert, update or delete to PictureUse will maintain this results table automatically for you.

1 Comment

+1 this is much better than an UDF when it comes to reads, the big caveat is that it serializes writes due to the lock on the count row.
0

you dont have to add the computed column to your table, because, after its updated,if the original table data got changed, then data become inconsistent , you can always use this select statement to get the column count, or create it as a view

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

Comments

-1

This will work

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 

Comments

-2

try this

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.