特別な方法で 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 の順序で、次のことを行います。
- cnt を選択して作業する
- Job_id の順に Jobs テーブルから最初に使用可能なワーカーを検索します
- 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 テーブル:
結果のジョブテーブル:
上記のループを置き換える効率的なクエリまたは更新ステートメントを探していますが、現在、ループの上記の動作を適切に置き換える方法は考えられません。