2

特別な方法で 2 つのテーブルを結合する必要があります。現在、結合はカーソルとループで行われており、データを処理するためのより効率的な方法を探しています。

最初の表は、todo アイテムのリストです。

create table todo
( todo_id int not null identity(1,1) primary key,
  cnt int not null,      -- how many units of work have to be completed?
  work char(1) not null  -- type of work, for example 'x', 'y', 'z'
);

たとえば、テーブルには次の値が含まれます

insert into todo (cnt, work) values (1, 'x'), (3, 'y'), (2, 'u'), (3, 'v'), (1, 'w');

これは、作業「x」を 1 回、作業「y」を 3 回、というように完了する必要があることを意味します。この todo テーブルの作業は、最初の「使用可能な」Job_id の Jobs テーブルの同じワーカーによって完了する必要があります。todo テーブルの各エントリは、Jobs テーブルの「cnt」エントリにつながります。

create table jobs
(job_id int not null identity(1,1) primary key,
 worker char(1) not null, -- name of worker, for example 'A', 'B', 'C'
 work char(1)
);

Jobs テーブルには、最初に次の値が入力されます。

insert into jobs (worker) values 
('A'),('B'),('C'),('A'),('C'),('B'),('A'),('B'),('C'),('A'),('B'),('C');

todo テーブルの各行の todo_id の順序で、次のことを行います。

  1. cnt を選択して作業する
  2. Job_id の順に Jobs テーブルから最初に使用可能なワーカーを検索します
  3. Jobs テーブルを cnt 回、ワーカーの作業で更新します

現在、このタスクを完了するために次の T-SQL コードを使用しています。

DECLARE @Cnt int, @work char(1);
DECLARE @Worker char(1);
DECLARE myCursor CURSOR LOCAL FAST_FORWARD FOR
  SELECT cnt, work from todo
OPEN myCursor
FETCH NEXT FROM myCursor INTO @cnt, @work
WHILE @@FETCH_STATUS = 0 BEGIN
  select top 1 @Worker=Worker from jobs where work is null;
  update top(@cnt) j
  set work=@work
  from jobs j
  where j.work is null and j.worker=@worker;
  FETCH NEXT FROM myCursor INTO @cnt, @work
END
CLOSE myCursor
DEALLOCATE myCursor

todo テーブル:

トドテーブル

結果のジョブテーブル:

結果のジョブ テーブル

上記のループを置き換える効率的なクエリまたは更新ステートメントを探していますが、現在、ループの上記の動作を適切に置き換える方法は考えられません。

4

1 に答える 1