10

私のDBには、Items(Id、...、ToatlViews int)とItemViews(id、ItemId、Timestamp)の2つのテーブルがあります。

ItemViewsテーブルには、サイトに到着したアイテムのすべてのビューを保存します。時々、ストアドプロシージャを呼び出してItems.ToatlViewsフィールドを更新したいと思います。カーソルを使用してこのSPを実行しようとしましたが、updateステートメントが間違っています。それを修正するのを手伝ってもらえますか?カーソルなしでこれを行うことはできますか?

CREATE PROCEDURE UpdateItemsViews
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DECLARE @currentItemId int
    DECLARE @currentItemCursor CURSOR
    SET @currentItemCursor = CURSOR FOR SELECT Id FROM dbo.Items

    OPEN @currentItemCursor
    FETCH NEXT FROM @currentItemCursor INTO @currentItemId
    WHILE @@FETCH_STATUS = 0
    BEGIN
        Update dbo.Items set TotalViews = count(*) 
              from dbo.ItemViews where ItemId=@currentItemId
        FETCH NEXT FROM @currentItemCursor INTO @currentItemId
    END   
END
GO
4

6 に答える 6

26

直接UPDATEステートメントを使用できます

update Items set TotalViews = 
     (select COUNT(id) from ItemViews where ItemViews.ItemId = Items.Id)

重要な場合は、これを行うためのさまざまな方法でパフォーマンスをテストすることをお勧めします。

于 2012-05-22T11:54:17.247 に答える
8

update ... fromカーソルの代わりに使用できます:

update  i
set     TotalViews = iv.cnt
from    dbo.Item i
join    (
        select  ItemId
        ,       count(*) as cnt
        from    dbo.ItemViews
        group by
                ItemId
        ) iv
on      i.Id = iv.ItemId
于 2012-05-22T11:50:22.293 に答える
3
;WITH x AS 
(
  SELECT ItemID, c = COUNT(*) 
  FROM dbo.ItemViews
  GROUP BY ItemID
)
UPDATE i
SET TotalViews = x.c
FROM dbo.Items AS i
INNER JOIN x
ON x.ItemID = i.ItemID;

しかし、実行時に常にカウントを取得できるのに、なぜこの値を保存したいのでしょうか。ItemViewsテーブルに何らかの方法で触れるたびに、この更新ステートメントを実行する必要があります。そうしないと、Itemsに保存されているカウントが正しくなくなります。

代わりに検討できるのは、インデックス付きビューを設定することです。

CREATE VIEW dbo.ItemViewCount
WITH SCHEMABINDING
AS
    SELECT ItemID, ItemCount = COUNT_BIG(*)
      FROM dbo.ItemViews
      GROUP BY ItemID;
GO
CREATE UNIQUE CLUSTERED INDEX x ON dbo.ItemViewCount(ItemID);

これで、クエリのビューに参加して、カウントが常に最新であることがわかります(各アイテムのカウントをスキャンするというペナルティを支払う必要はありません)。インデックス付きビューの欠点は、ItemViewsテーブルへの挿入/更新/削除がある場合に、そのコストを段階的に支払うことです。

于 2012-05-22T11:56:03.703 に答える
0

同じだが異なる:

declare @productId int = 24;
declare @classificationTypeId int = 86;

update s
set CounterByProductAndClassificationType = row_num
from Samples s
join
(
    select row_number() over (order by (select Id)) row_num, Id
    from Samples
    where 
        ProductId = @productId and
        ClassificationTypeId = @classificationTypeId
) s_row on s.Id = s_row.Id
于 2015-07-14T13:02:43.597 に答える