C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: SQL Server2005のストアドのループ内でUNION


(過去ログ 77 を表示中)

[トピック内 3 記事 (1 - 3 表示)]  << 0 >>

■45365 / inTopicNo.1)  SQL Server2005のストアドのループ内でUNION
  
□投稿者/ ゆる (18回)-(2010/01/11(Mon) 10:49:30)

分類:[データベース全般] 

SQL Server2005にて、
開始日、終了日、間隔を指定して、以下のような結果を得たいと思っています。

開始日:2010/1/10 終了日:2010/1/13 間隔:1日ごと

Data_from     Date_to
2010/1/10 0:00:00 2010/1/10 23:59:59
2010/1/11 0:00:00 2010/1/11 23:59:59
2010/1/12 0:00:00 2010/1/12 23:59:59

開始日や終了日、間隔を任意に指定できるようにしようと、
以下のストアドを書いたのですが、うまく動いてくれません。

WHILE内のUNION ALL句があると、
「キーワード 'UNION' 付近に不適切な構文があります。」と言われてしまいます。



CREATE         PROCEDURE [dbo].[XXXX]
			 	@Set_Date_from	datetime
			 	,@Set_Date_to	datetime
				,@Set_datepart	nvarchar(10)
				,@Set_num	int
AS

DECLARE 
	@Date_from as datetime
	,@Date_to as datetime

BEGIN

set @Date_from = @Set_Date_from

--最初の1行目
SET @Date_to = 
case @Set_datepart
	WHEN 'dd' THEN Dateadd(dd , @Set_num, @Date_from)
	WHEN 'mm' THEN Dateadd(mm , @Set_num, @Date_from)
	WHEN 'yy' THEN Dateadd(yy , @Set_num, @Date_from)
	ELSE Dateadd(dd , @Set_num, @Date_from)
END

SELECT
	@Date_from AS Date_from	,
	Dateadd(ss,-1,@Date_to) AS Date_To	

--2行目以降
	WHILE @Date_to < @Set_Date_to
	BEGIN
		--fromの取得
		SET @Date_from = @Date_to

		--toの取得
		SET @Date_to = 
		CASE @Set_datepart
			WHEN 'dd' THEN Dateadd(dd , @Set_num, @Date_from)
			WHEN 'mm' THEN Dateadd(mm , @Set_num, @Date_from)
			WHEN 'yy' THEN Dateadd(yy , @Set_num, @Date_from)
			ELSE Dateadd(dd , @Set_num, @Date_from)
		END

--		UNION ALL --これがあるとエラーが出る。
		SELECT
			@Date_from AS Date_from	,
			Dateadd(ss,-1,@Date_to) AS Date_To	
	END
END


期待する結果を得るにはどのようにすれば良いでしょうか。
もしくはもっと良い方法があるようならアドバイス頂ければ幸いです。
どうかよろしくお願いします。


引用返信 編集キー/
■45402 / inTopicNo.2)  Re[1]: SQL Server2005のストアドのループ内でUNION
□投稿者/ 魔界の仮面弁士 (1447回)-(2010/01/12(Tue) 11:42:47)
No45365 (ゆる さん) に返信
> 開始日:2010/1/10 終了日:2010/1/13 間隔:1日ごと
> Data_from     Date_to
> 2010/1/10 0:00:00 2010/1/10 23:59:59
> 2010/1/11 0:00:00 2010/1/11 23:59:59
> 2010/1/12 0:00:00 2010/1/12 23:59:59

上記だと、CONVERT(datetime, '2010-01-11 23:59:59.870') などは
どの範囲にも該当しないことになってしまいそうですが、本当に大丈夫ですか?

それらの値を何に使うのか分かりませんが、もしも「以上/以下」の範囲で
 WHERE A.dt BETWEEN B.Data_from AND B.Date_to
のような使い方を目的としているのであれば、「以上/未満」の範囲にするため、
from/to 共に日付部のみ(つまり、時刻部 = 00:00:00.000)にしておいた上で、
 WHERE A.dt >= B.Data_from AND A.dt < B.Date_to
のように利用された方が安全かと思います。


> 開始日や終了日、間隔を任意に指定できるようにしようと、
> 以下のストアドを書いたのですが、うまく動いてくれません。

利用目的にもよりますが、テーブルを返す関数を用いるのは如何でしょうか。

/* 利用方法 */
SELECT * FROM dbo.Orator('2010-01-10', '2010-01-13', 'dd', 1)

/* 結果 */
Date_from                  Date_to
-----------------------    -----------------------
2010-01-10 00:00:00.000    2010-01-11 00:00:00.000
2010-01-11 00:00:00.000    2010-01-12 00:00:00.000
2010-01-12 00:00:00.000    2010-01-13 00:00:00.000

/* ストアドファンクション */
CREATE FUNCTION dbo.Orator
(
	@Set_Date_from  datetime,
	@Set_Date_to    datetime,
	@Set_datepart   nvarchar(10),
	@Set_num	    int
)
RETURNS @TBL TABLE
(
	Date_from  datetime,
	Date_to    datetime
)
AS
BEGIN

	DECLARE @Date_from as datetime
	DECLARE @Date_to   as datetime
	SET @Date_from = @Set_Date_from

	WHILE @Date_from < @Set_Date_to
	BEGIN
		SET @Date_to = CASE @Set_datepart
		  WHEN 'yy' THEN Dateadd(yy , @Set_num, @Date_from)
		  WHEN 'mm' THEN Dateadd(mm , @Set_num, @Date_from)
		  ELSE Dateadd(dd , @Set_num, @Date_from)
		END

		INSERT INTO @TBL (Date_from, Date_to) VALUES(@Date_from, @Date_to)

		SET @Date_from = @Date_to
	END

	RETURN
END

引用返信 編集キー/
■45406 / inTopicNo.3)  Re[2]: SQL Server2005のストアドのループ内でUNION
□投稿者/ ゆる (19回)-(2010/01/12(Tue) 15:11:27)
No45402 (魔界の仮面弁士 さん) に返信

魔界の仮面弁士さま

回答ありがとうございます。期待通りの結果を得ることができました。
ご推察の通り、集計的なことを行うための日付範囲の取得が目的でして、
ご教示頂いたような形で行うようにしたいと思います。

とても勉強になりました。
ありがとうございましたm(_ _)m


解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -