2016-06-28 19 views
-3

を持つSQL Serverこれは私がSQL Serverで達成しようとしているものですが、運はありません。列をピボット列にピボットするのに役立つ必要があります。

は、私は。これは私がCount列が3であれば、私はあなたの助けに感謝3行

ID Start Dt End Dt Count 
1 3/1/2016 4/1/2016 1 
1 4/1/2016 5/1/2016 1 
1 5/1/2016 6/1/2016 1 

を生成する必要があり、必要なものである

ID Start Dt End Dt Count 
1 3/1/2016 6/1/2016 3 

、以下のような表を持って

+0

我々はそれをデバッグに役立つことができるように、あなたの試みを投稿してください。 「運がない」とはどういう意味ですか?間違いましたか? –

+0

元のテーブルに表示されない日付を生成するには、カレンダーテーブルが必要になると思います。 –

+1

実際にピボットではありません。あなたはカレンダーテーブルが必要ですし、始まりdtと終わりDt - >検索stackoverflowの間にそれに参加し、そこにはたくさんの答えがあります。 –

答えて

1

私は、UDFを使用して動的な日付範囲を作成します(下記参照)。私は多対多を示すためにサンプルデータに別の行を追加しました。

Declare @Table table (ID int,StartDt Date,EndDate Date,Count int) 
Insert into @Table values 
(1,'2016-03-01','2016-06-01',3), 
(2,'2016-02-01','2016-07-01',22) 


Declare @MinDate Date,@MaxDate Date 
Select @MinDate=min(StartDt),@MaxDate=max(EndDate) from @Table 

Select ID,DateR1,DateR2,Count=cast((Count+0.0)/DateDiff(MM,StartDt,EndDate) as money) 
    From @Table A 
    Join (Select DateR1=RetVal,DateR2=DateAdd(MM,1,RetVal) From [dbo].[udf-Create-Range-Date](@MinDate,@MaxDate,'MM',1)) B 
    on DateR1 Between StartDt and EndDate and DateR1<EndDate 

戻り

ID DateR1  DateR2  Count 
1 2016-03-01 2016-04-01 1.00 
1 2016-04-01 2016-05-01 1.00 
1 2016-05-01 2016-06-01 1.00 
2 2016-02-01 2016-03-01 4.40 
2 2016-03-01 2016-04-01 4.40 
2 2016-04-01 2016-05-01 4.40 
2 2016-05-01 2016-06-01 4.40 
2 2016-06-01 2016-07-01 4.40 

UDF

CREATE FUNCTION [dbo].[udf-Create-Range-Date] (@DateFrom datetime,@DateTo datetime,@DatePart varchar(10),@Incr int) 

Returns 
@ReturnVal Table (RetVal datetime) 

As 
Begin 
    With DateTable As (
     Select DateFrom = @DateFrom 
     Union All 
     Select Case @DatePart 
       When 'YY' then DateAdd(YY, @Incr, df.dateFrom) 
       When 'QQ' then DateAdd(QQ, @Incr, df.dateFrom) 
       When 'MM' then DateAdd(MM, @Incr, df.dateFrom) 
       When 'WK' then DateAdd(WK, @Incr, df.dateFrom) 
       When 'DD' then DateAdd(DD, @Incr, df.dateFrom) 
       When 'HH' then DateAdd(HH, @Incr, df.dateFrom) 
       When 'MI' then DateAdd(MI, @Incr, df.dateFrom) 
       When 'SS' then DateAdd(SS, @Incr, df.dateFrom) 
       End 
     From DateTable DF 
     Where DF.DateFrom < @DateTo 
    ) 

    Insert into @ReturnVal(RetVal) Select DateFrom From DateTable option (maxrecursion 32767) 

    Return 
End 

-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','YY',1) 
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2020-10-01','DD',1) 
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-31','MI',15) 
-- Syntax Select * from [dbo].[udf-Create-Range-Date]('2016-10-01','2016-10-02','SS',1) 
+0

こんにちはJohn、ありがとう。関数を作成するときに、このエラーが発生します。レベル16、状態1、プロシージャudf-Create-Range-Date、12行 マルチパート識別子 "df.dateFrom"をバインドできませんでした。 メッセージ4104、レベル16、状態1、プロシージャudf-Create-Range-Date、行13 マルチパート識別子「df.dateFrom」はバインドできませんでした。 メッセージ4104、レベル16、状態1、手順udf-Create-Range-Date、14行 – user138770

+0

大文字と小文字を区別します。すべてのdfを検索して置き換えます。 DFで –

+0

それは働いた。あまりにもジョン...ありがとうございました。 – user138770

0

これは別の方法であり、それは動作します。

declare @temp_table table (
     id int, 
     start_date date, 
     end_date date, 
     count_no int 
    ) 

    insert into @temp_table values (1,'3/1/2016','6/1/2016',3) 

    select * from @temp_table 

上記のクエリは元の結果を返します。そして、クエリの下で期待どおりの結果が返されます。

;with temp(count) as (
    select 1 
    union all 
    select count + 1 
    from temp 
    where count < (select count_no from @temp_table) 
) 
select tt.id, 
    convert(char, dateadd(month,count -1 , tt.start_date), 101) as start_date, 
    convert(char, dateadd(month,count,tt.start_date) , 101) as end_date, 
    count(*) as count 

from temp as t cross join @temp_table as tt 
group by tt.id,tt.start_date,t.count 

HTH

+0

素晴らしい、マリンありがとう.. – user138770

関連する問題