2

理解を助けるために、次のような表があります。

itemcode itemname icode serialnum
1        A        10    0
2        B        10    0
3        C        10    0
4        D        11    0
5        E        13    0
6        F        20    0
7        G        20    0

ループカーソルを使用して単一の更新クエリを使用して、結果を次の表のようにしたいと考えています。

itemcode itemname icode serialnum
1        A        10    1
2        B        10    2
3        C        10    3
4        D        11    1
5        E        13    1
6        F        20    1
7        G        20    2

品目コードは、この表の主キーです。シリアル番号を生成する背後にあるロジックは、icode がシリアル番号を変更するたびに、シリアル番号が 1 にリセットされることです。誰かが解決策を支援できる場合、カーソルを使用してテーブルを更新する単一の更新クエリが必要ですか?

4

2 に答える 2

3

SQL フィドル

MS SQL Server 2008 スキーマのセットアップ:

create table Item
(
  itemcode int,
  itemname char(1),
  icode int,
  serialnum int
)

insert into Item values
(1, 'A', 10, 0),
(2, 'B', 20, 0),
(3, 'C', 11, 0),
(4, 'D', 10, 0),
(5, 'E', 20, 0),
(6, 'F', 10, 0),
(7, 'G', 13, 0)

クエリ 1 :

update I
set serialnum = rn
from
  (
    select serialnum,
           row_number() over(partition by icode order by itemcode) as rn
    from Item
  ) I

select *
from Item

結果

| ITEMCODE | ITEMNAME | ICODE | SERIALNUM |
-------------------------------------------
|        1 |        A |    10 |         1 |
|        2 |        B |    20 |         1 |
|        3 |        C |    11 |         1 |
|        4 |        D |    10 |         2 |
|        5 |        E |    20 |         2 |
|        6 |        F |    10 |         3 |
|        7 |        G |    13 |         1 |

アップデート

カーソルを使わない代わりにカーソルを使うバージョン。

SQL フィドル

declare @itemcode int
declare @rn int

declare ItemCursor cursor local static forward_only read_only for 
select itemcode,
       row_number() over(partition by icode order by itemcode) as rn
from Item

open ItemCursor

fetch next from ItemCursor
into @itemcode, @rn

while @@fetch_status = 0
begin
  update Item
  set serialnum = @rn
  where itemcode = @itemcode

  fetch next from ItemCursor
  into @itemcode, @rn
end

close ItemCursor
deallocate ItemCursor
于 2012-11-14T09:22:18.263 に答える
3

したがって、すべての icode-group に連続したシリアル番号が必要です。ROW_NUMBER次に、次のように使用できますPARTITION BY icode

WITH CTE AS
(
  SELECT itemcode, itemname, icode, serialnum,
     ,   ROW_NUMBER() OVER (PARTITION BY icode ORDER BY itemcode) AS RN
  FROM dbo.TableName 
)
UPDATE CTE SET serialnum = RN;

更新ごとに再計算する場合は、トリガーを使用できます。

CREATE TRIGGER dbo.TableName_Updated
ON dbo.TableName 
FOR UPDATE /* Fire this trigger when one or multiple rows are UPDATEd */
AS BEGIN
    WITH CTE AS
    (
      SELECT itemcode, itemname, icode, serialnum,
         ,   ROW_NUMBER() OVER (PARTITION BY icode ORDER BY itemcode) AS RN
      FROM dbo.TableName t INNER JOIN INSERTED i 
        ON t.itemcode = i.itemcode
    )
    UPDATE CTE SET serialnum = RN
END
于 2012-11-14T09:24:02.260 に答える