- ベストアンサー
SQL SERVER2005でシフト表を出力したい
- SQL SERVER2005を使用して社員のシフト管理表を作成し、CSVにエクスポートする方法について相談したいです。
- 予定テーブルと社員予定テーブルを結合して、アサインされている社員が表示される表を作成したいです。
- 入力時の制限として、予定テーブルの人数よりも多い数の社員は割り当てられていません。
- みんなの回答 (2)
- 専門家の回答
質問者が選んだベストアンサー
あ、ごめんなさい。 ANo1のものです。 ミスしてます。 ANo1では、 yotei_id jishi_day ninzu shiten shain_yotei_id shain_nam 5 2011/7/5 3 支店B Null Null ができてしまいます。 >insert into #TMP >select a.yotei_id,a.jishi_day,a.ninzu,a.shiten,b.shain_yotei_id,b.shain_nam >from tbl_yotei a,tbl_shain_yotei b where a.yotei_id = b.yotei_id > >を実行する。(shain_yotei_idとshain_namがNULLでないレコードが格納される) まではいいのですが、 >select max(ninzu) from tbl_yotei >の値を取得する。 ここは、 select yotei_id,ninzu from tbl_yotei をカーソルで取得して、1件ずつ処理する必要があります。 > >while等を使って1から上で取得したmax(ninzu)まで以下のSQLを繰り返す。 >insert into #TMP >select a.yotei_id,a.jishi_day,a.ninzu,a.shiten,NULL,NULL >from tbl_yotei a >where (select count(*) from #temp b where b.yotei_id = a.yotei_id) < 繰り返しの値 これは、上で取得したレコード毎に繰り返し処理します。 ということで、 (元質問に書かれているのと同様に) DECLARE c_yotei cursor FOR SELECT yotei_id,ninzu FROM tbl_yotei OPEN c_yotei FETCH NEXT FROM c_yotei INTO @yotei_id, @ninzu WHILE @@FETCH_STATUS = 0 BEGIN set @i = 1 while @i > @ninzu insert into #TMP select a.yotei_id,a.jishi_day,a.ninzu,a.shiten,NULL,NULL from tbl_yotei a where a.yotei_id = @wk_yotei_ID and (select count(*) from #temp b where b.yotei_id = @wk_yotei_ID) < @i set @i = @i + 1 end FETCH NEXT FROM c_yotei INTO @yotei_id, @ninzu end ということで。 (すいませんでした。)
その他の回答 (1)
- Siegrune
- ベストアンサー率35% (316/895)
## 単に外部結合するだけで実現できると思いきや、甘かった。 方法案 #TMPは、yotei_id,jishi_day,ninzu,shiten,shain_yotei_id,shain_nam にする。 insert into #TMP select a.yotei_id,a.jishi_day,a.ninzu,a.shiten,b.shain_yotei_id,b.shain_nam from tbl_yotei a,tbl_shain_yotei b where a.yotei_id = b.yotei_id を実行する。(shain_yotei_idとshain_namがNULLでないレコードが格納される) select max(ninzu) from tbl_yotei の値を取得する。 while等を使って1から上で取得したmax(ninzu)まで以下のSQLを繰り返す。 insert into #TMP select a.yotei_id,a.jishi_day,a.ninzu,a.shiten,NULL,NULL from tbl_yotei a where (select count(*) from #temp b where b.yotei_id = a.yotei_id) < 繰り返しの値 例示されたものでは、繰り返しの値は、1から3まで処理されます。 yotei_id=3の部分だけでいうと、count(*)は2。 繰り返しの値が1のときは、 (select count(*) from #temp b where b.yotei_id = a.yotei_id) < 1 何もしない。 繰り返しの値が2のときは、 (select count(*) from #temp b where b.yotei_id = a.yotei_id) < 2 何もしない。 繰り返しの値が3のときは、 (select count(*) from #temp b where b.yotei_id = a.yotei_id) < 3 は成立。 insert into #TMP select a.yotei_id,a.jishi_day,a.ninzu,a.shiten,NULL,NULL from tbl_yotei a が実行される。 といった具合です。
お礼
Siegrune様 投稿ありがとうございます。 そうなんです。聞いた感じだとまあできそうな気がしていたのですが、いざやってみるととても大変でびっくりしています。 データのある行を先に#TMPに入れてしまってその後nullだけという二段階のインサート!私はぜんぜん思いつきませんでした! いただいたアイデアを元に作成してみます。 max(ninzu)の結果を変数に入れる方法などまだわかっていないので調べて組み立ててみます。 本当にありがとうございます! 他のアイデアがありましたらどうぞ投稿お願いいたします。
お礼
Siegrune様 再度投稿ありがとうございます。 >すいませんでした。 とんでもないです。こちらこそ何度もお答えいただいてありがとうございます。 実は先ほど一度教えていただいたストアドを書いてみて今回ご指摘の結果になる事にきづき、改めて考えていた所でございました! 各レコードのninzuの数だけ調べるという事ですね。ありがとうございます。 しかし、今回の大きなヒントになったのはNULLを後にインサートするという所がポイントとなり前に進めました! ありがとうございます。
補足
Siegrune様 できました!!ありがとうございました!! 下記ストアドプロシージャで思った結果が出てきました。 --- ALTER PROCEDURE dbo.StoredProcedure1 AS DECLARE @yotei_id INT DECLARE @ninzu int --一時テーブル CREATE TABLE #TMP ( yotei_id INT, jishi_day DATETIME, ninzu INT, shiten NVARCHAR(50), shain_yotei_id INT, shain_nam NVARCHAR(50) ) INSERT INTO #TMP SELECT a.yotei_id, a.jishi_day, a.ninzu, a.shiten, b.shain_yotei_id, b.shain_nam FROM tbl_yotei a, tbl_shain_yotei b WHERE a.yotei_id = b.yotei_id DECLARE c_yotei CURSOR FOR SELECT yotei_id,ninzu FROM tbl_yotei OPEN c_yotei FETCH NEXT FROM c_yotei INTO @yotei_id, @ninzu WHILE @@FETCH_STATUS = 0 BEGIN DECLARE @i INT SET @i = 0 WHILE @i < @ninzu BEGIN INSERT INTO #TMP SELECT a.yotei_id, a.jishi_day, a.ninzu, a.shiten, NULL, NULL FROM tbl_yotei a WHERE a.yotei_id = @yotei_id AND (SELECT COUNT(*) FROM #TMP b WHERE b.yotei_id = @yotei_id) <= @i SET @i = @i + 1 END FETCH NEXT FROM c_yotei INTO @yotei_id, @ninzu END SELECT * FROM #TMP ORDER BY yotei_id RETURN --- 【結果】 yotei_id jishi_day ninzu shiten shain_yotei_id shain_nam 1 2011/07/01 0:00:00 2 支店A 1 田中 1 2011/07/01 0:00:00 2 支店A 2 山根 2 2011/07/02 0:00:00 1 支店A 3 杉下 3 2011/07/03 0:00:00 3 支店A 4 田中 3 2011/07/03 0:00:00 3 支店A 5 一条 3 2011/07/03 0:00:00 3 支店A 4 2011/07/02 0:00:00 1 支店B 6 魚島 5 2011/07/03 0:00:00 2 支店B 5 2011/07/03 0:00:00 2 支店B 6 2011/07/04 0:00:00 3 支店A 6 2011/07/04 0:00:00 3 支店A 6 2011/07/04 0:00:00 3 支店A --- 助かりました。本当にありがとうございました。