2011-08-08 14 views
1

私は以下のスクリプト例のように、関連のテーブルに持っている:私は、ユーザーの挿入/更新/レビューを削除したときに製品の行にAvgRatingを計算したい子テーブルの挿入/更新/削除で親テーブルの列の値を更新するにはどうすればよいですか?

-- Creating table 'Product' 
CREATE TABLE [dbo].[Product] (
    [Id] int IDENTITY(1,1) NOT NULL, 
    [Text] nvarchar(max) NOT NULL, 
    [AvgRating] decimal(18,2) NOT NULL 
); 
GO 

-- Creating table 'Review' 
CREATE TABLE [dbo].[Review] (
    [Id] int IDENTITY(1,1) NOT NULL, 
    [Text] nvarchar(max) NOT NULL, 
    [Rating] decimal(18,2) NOT NULL, 
    [Product_Id] int NOT NULL 
); 
GO 

-- Creating primary key on [Id] in table 'Product' 
ALTER TABLE [dbo].[Product] 
ADD CONSTRAINT [PK_Product] 
    PRIMARY KEY CLUSTERED ([Id] ASC); 
GO 

-- Creating primary key on [Id] in table 'Review' 
ALTER TABLE [dbo].[Review] 
ADD CONSTRAINT [PK_Review] 
    PRIMARY KEY CLUSTERED ([Id] ASC); 
GO 

-- Creating foreign key on [Product_Id] in table 'Review' 
ALTER TABLE [dbo].[Review] 
ADD CONSTRAINT [FK_ProductReview] 
    FOREIGN KEY ([Product_Id]) 
    REFERENCES [dbo].[Product] 
     ([Id]) 
    ON DELETE NO ACTION ON UPDATE NO ACTION; 

-- Creating non-clustered index for FOREIGN KEY 'FK_ProductReview' 
CREATE INDEX [IX_FK_ProductReview] 
ON [dbo].[Review] 
    ([Product_Id]); 
GO 

。私の頭に浮かぶ最も明白で力強いアプローチは、データベースからデータを取り出し、クライアント側の平均を計算し、次に製品の行を手動で更新することです。それはデータをプルする必要なくデータベースサーバー上で自動的に行うことが可能ですか?もしそうなら、どうですか?データベースはMS SQL Server 2008でホストされています。

答えて

2

レビューテーブルにトリガを作成できます。レビューの更新後、平均レビューを再計算することができます。

CREATE TRIGGER TRG_REVIEW 
ON Review 
AFTER INSERT, UPDATE, DELETE 
AS 

;WITH ratings 
AS 
(
    SELECT product_id, AVG(Rating) AS rating 
    FROM Review R 
    WHERE EXISTS (SELECT * FROM INSERTED WHERE product_id = R.product_id AND UPDATE(rating)) 
     OR EXISTS (SELECT * FROM DELETED WHERE product_id = R.product_id) 
    GROUP BY product_id 
) 
UPDATE P set AvgRating = COALESCE(R.rating,0) 
FROM Product P 
INNER JOIN ratings R 
ON P.id = R.Product_id 
+0

ありがとうございます、魅力的な作品です。あまりにも悪い私はあなたの答えをまだupvoteできません。 – kondzik

+0

私の喜び、助けて嬉しいです!私はそのトリガーにバグを修正しました。削除されたテーブルはCTEとINSERTEDで参照される必要がありました。 –

+0

そして、私はあなたにセットベースのトリガーを書くために余分なポイントを与えるだろう – HLGEM

関連する問題