2016-06-28 78 views
-3

這是我想在SQL Server中實現的,但沒有運氣。需要幫助將列數據透視到行SQL Server with count

我有表如下

ID Start Dt End Dt Count 
1 3/1/2016 6/1/2016 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 

感謝您的幫助..

+0

請發表您的嘗試,這樣我們可以幫助調試。 「沒有運氣」是什麼意思?你有錯誤嗎? –

+0

我想你將需要一個日曆表來生成那些日期沒有出現在你的原始表中。 –

+1

不是真正的PIVOT。你需要一個日曆表,並使用BETWEEN start dt和End Dt - > search 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」。 Msg 4104,Level 16,State 1,Procedure udf-Create-Range-Date,Line 13 無法綁定多部分標識符「df.dateFrom」。 Msg 4104,Level 16,State 1,Procedure udf-Create-Range-Date,Line 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

真棒,謝謝Marin .. – user138770