重做功能仅作为SQL调用

时间:2014-07-30 20:41:41

标签: sql sql-server tsql sql-server-2005

我要求我使用C#进行编码,但我认为我可以在SQL中进行编码但是如果不使用一堆光标我就无法理解。我有一张看起来像这样的表:

Row_Type Period_1  Period_2  Period_3 ... Period_18
FFT      600.0     200.0     300.0        0.0
END      500.0     150.0     200.0        0.0
WK#        2.0       0.5       1.0        0.0

WK#是当前Period之后可以进入当前END值的Period的EFT值的数量。因此,对于Period_1END为500,涵盖Period_2 FFT(200.0)和Period_3 FFT(300.0),因此WK#为2.0。 Period_2 END为150.0,仅覆盖Period_3 FFT的50%,因此其WK#为0.5。所有18个时期都在继续。

任何想法如何在SQL中解决这个问题。我正在使用MS SQL Server 2005。

FFT是期间所需的小部件的预期数量,END是期间手头的小部件数量,WK#是手头小部件供应的期末数量(END)可以满足。因此,在Period_1的示例数据中,我们预测我们将有足够的供应(END)来覆盖下两个周期(WK#= 2.0)的预期需求(FFT)。期间通常是一周,因此它被称为WK#。

很抱歉我现在意识到这一点尚不清楚,但我正在尝试计算WK#,我有FFT和END值

2 个答案:

答案 0 :(得分:0)

也许像..

declare @t table (Row_Type varchar(10), Period_1 decimal(8,2), Period_2 decimal(8,2), Period_3 decimal(8,2), Period_4 decimal(8,2))
insert into @t (Row_Type, Period_1, Period_2, Period_3, Period_4)
select 'FFT', 600.0, 200.0, 300.0, 0.0
union all
select 'WK#', 2.0, 0.5, 1.0, 0.0
    if object_id('tempdb..#temptable') is not null
drop table #temptable

select Row_Number() over (order by Row_Type) as rownum, Row_Type, Period, PerValue
    into #temptable
from
    ( select Row_Type, Period_1, Period_2, Period_3, Period_4
    from @t
    where row_Type = 'FFT'
    ) as p
    unpivot
    (PerValue for Period in (Period_1, Period_2, Period_3, Period_4)) as unpvt;

insert into @t (Row_Type, Period_1, Period_2, Period_3, Period_4)
    select 
        'END' as Row_Type
        , (select sum(PerValue) * case when Period_1 < 1 then Period_1 else 1 end from #temptable where rownum >= 2 and rownum <= round(1 + Period_1,0,0) ) as Period_1
        , (select sum(PerValue) * case when Period_2 < 1 then Period_2 else 1 end  from #temptable where rownum >= 3 and rownum <= round(2+ Period_1,0,0) ) as Period_2
        , (select sum(PerValue) * case when Period_3 < 1 then Period_3 else 1 end  from #temptable where rownum >= 4 and rownum <= round(3+ Period_1,0,0) ) as Period_3
        , 0.0 as Period_4
    from @t
    where Row_Type = 'WK#'

select *
from @t

下面的修改示例。可能有更好的解决方案(使用函数或其他逻辑)

    declare @t table (Row_Type varchar(10), Period_1 decimal(8,2), Period_2 decimal(8,2), Period_3 decimal(8,2), Period_4 decimal(8,2))

insert into @t (Row_Type, Period_1, Period_2, Period_3, Period_4)
select 'FFT', 600.0, 200.0, 300.0, 0.0
union all
select 'END', 500.0, 150.0, 200.0, 0.0

insert into @t (Row_Type, Period_1, Period_2, Period_3, Period_4)
select 
    case
        when RTEND.Period_1 <= RTFFT.Period_2 then RTEND.Period_1 / RTFFT.Period_2
        when RTEND.Period_1 <= (RTFFT.Period_2 + RTFFT.Period_3) then 2.0
        when RTEND.Period_1 <= (RTFFT.Period_2 + RTFFT.Period_3 + RTFFT.Period_4) then 3.0
        end as Period_1
    ,   case
        when RTEND.Period_2 <= RTFFT.Period_3 then RTEND.Period_2 / RTFFT.Period_3
        when RTEND.Period_2 <= (RTFFT.Period_3 + RTFFT.Period_4) then 2.0
        end as Period_2
    , case
        when RTEND.Period_3 <= RTFFT.Period_4 then RTEND.Period_3 / RTFFT.Period_4 
        else 1.0
        end as Period_3
    , 0.0 AS Period_4
from
(
    select 1 as ID, *
    from @t
    where Row_Type = 'FFT'
) RTFFT
inner join
(
    select 1 as ID, *
    from @t
    where Row_Type = 'END'
) RTEND
on RTFFT.ID = RTEND.ID

select *
from @t

答案 1 :(得分:0)

这意大利面是我今天想出来的。它有效,但它不漂亮。我从凯文库克提出的建议开始(我不让他对结果负责)

if object_id('tempdb..#LookupGFT') is not null
drop table #LookupGFT

if object_id('tempdb..#TempCalc') is not null
drop table #TempCalc


SELECT *
INTO #LookupGFT
FROM(
SELECT ROW_NUMBER() OVER(ORDER BY Period) RowNo, Period, GFT 
FROM
(SELECT period01, period02, period03, period04, period05, period06, period07, period08, period09, period10, period11, period12, period13, period14, 
                      period15, period16, period17
FROM         CombineSnapshot_detail
WHERE row_type = 'GFT') p
UNPIVOT
(GFT FOR Period IN (period01, period02, period03, period04, period05, period06, period07, period08, period09, period10, period11, period12, period13, period14, 
                      period15, period16, period17)) as unpvt) adb


SELECT style_pkey, Period, [END], [WK#], IsNull(WholePeriods,0) as WholePeriods, IsNull(wholePeriodsTotal,0) as wholePeriodsTotal, IsNull(RemainderGFT,0) as RemainderGFT
INTO #TempCalc
FROM
(SELECT RowNo, style_pkey, Period, [END], [WK#], 
CASE WHEN [END] < 1 THEN 0 ELSE (SELECT MAX(rowNo) FROM 
    (SELECT RowNo, Period, GFT, isNull((SELECT SUM(GFT) FROM #LookupGFT WHERE (RowNo - mainData.RowNo <= lup2.RowNo) and (RowNo > mainData.RowNo)),0) RUNNING_TOTAL
    FROM(
        SELECT ROW_NUMBER() OVER(ORDER BY Period) RowNo, Period, GFT
        FROM(
            SELECT Period, GFT
            FROM #LookupGFT LGFT
            WHERE RowNo > mainData.RowNo
            ) Lup1
        ) lup2
    ) abc WHERE abc.RUNNING_TOTAL < mainData.[END]) END as wholePeriods,
CASE WHEN [END] < 1 THEN 0 ELSE (SELECT MAX(RUNNING_TOTAL) FROM 
    (SELECT RowNo, Period, GFT, isNull((SELECT SUM(GFT) FROM #LookupGFT WHERE (RowNo - mainData.RowNo <= lup2.RowNo) and (RowNo > mainData.RowNo)),0) RUNNING_TOTAL
    FROM(
        SELECT ROW_NUMBER() OVER(ORDER BY Period) RowNo, Period, GFT
        FROM(
            SELECT Period, GFT
            FROM #LookupGFT LGFT
            WHERE RowNo > mainData.RowNo
            ) Lup1
        ) lup2
    ) abc WHERE abc.RUNNING_TOTAL < mainData.[END]) END as wholePeriodsTotal,

CASE WHEN [END] < 1 THEN 0 ELSE (SELECT TOP (1) GFT FROM 
    (SELECT RowNo, Period, GFT, isNull((SELECT SUM(GFT) FROM #LookupGFT WHERE (RowNo - mainData.RowNo <= lup2.RowNo) and (RowNo > mainData.RowNo)),0) RUNNING_TOTAL
    FROM(
        SELECT ROW_NUMBER() OVER(ORDER BY Period) RowNo, Period, GFT
        FROM(
            SELECT Period, GFT
            FROM #LookupGFT LGFT
            WHERE RowNo > mainData.RowNo
            ) Lup1
        ) lup2
    ) abc WHERE abc.RUNNING_TOTAL > mainData.[END] ORDER BY RowNo) END as RemainderGFT

FROM(
SELECT ROW_NUMBER() OVER(ORDER BY Period) RowNo, style_pkey, Period, [END], CAST(0 as FLOAT) as [WK#]
FROM
(SELECT style_pkey, period01, period02, period03, period04, period05, period06, period07, period08, period09, period10, period11, period12, period13, period14, 
                      period15, period16, period17
FROM         CombineSnapshot_detail
WHERE row_type = 'END') p
UNPIVOT
([END] FOR Period IN (period01, period02, period03, period04, period05, period06, period07, period08, period09, period10, period11, period12, period13, period14, 
                      period15, period16, period17)) as unpvt) as mainData) completedData


UPDATE #TempCalc
SET [WK#] = CASE WHEN (wholePeriodsTotal + RemainderGFT) > 0 THEN Round(((([END] - wholePeriodsTotal)/RemainderGFT) + wholePeriods),1) ELSE 0.0 END
FROM #TempCalc


SELECT Style_Pkey, 'WK#' as row_type, [period01], [period02], [period03], [period04], [period05], [period06], [period07], [period08], [period09], [period10], [period11], [period12], [period13], [period14], 
                      [period15], [period16], [period17]
FROM
(SELECT Style_Pkey, period, [WK#] 
    FROM #TempCalc) AS SourceTable
PIVOT
(
MAX([WK#])
FOR period IN ([period01], [period02], [period03], [period04], [period05], [period06], [period07], [period08], [period09], [period10], [period11], [period12], [period13], [period14], 
                      [period15], [period16], [period17])
) AS PivotTable;