0

我正在 MSSQL Server Management Studio 中编写此查询,我遇到了心理障碍。假设我有几座建筑物,当它们上线时,我想将它们的产量与预测的 P_AMOUNT 和 F_AMOUNT 进行比较。这是两个独立的数据库,通过查询组合成一个(即生产数据库和预测数据库)。

在此处输入图像描述

所以我的问题是。我想在预测每个 B_ID 的同时选择此处的峰值产量。大多数建筑物都像 B_ID #2 并且有预测数量,但偶尔会有一个没有。像 B_ID #1。如果 F_Amount = 0,我将如何仅将 F_Date 的日期向前滚动一个月?

SELECT P1.B_ID, P1.P_DATE, P1.P_AMOUNT, F1.F_DATE, F1.F_AMOUNT
FROM DB1.Production P1
INNER JOIN DB2.Forecast F1
ON P1.DB_ID = F1.DB_ID
4

2 回答 2

0

有几种方法可以解决您的问题。一种方法是根据F_DATE和何时对每一行进行排名F_AMOUNT值为零对每一行进行排名,以拉下一行由于您没有指定 SQL Server 的版本,因此我使用了适用于 SQL Server 2005 或更高版本的语法。

With RnkItems As
    (
    Select B_ID, P_DATE, P_AMOUNT, F_DATE, F_AMOUNT 
        , Row_Number() Over ( Order By F_DATE ) As Rnk
    From SourceData
    )
Select R.B_ID, R.P_DATE, R.P_AMOUNT
    , R.F_DATE As [Original F_DATE]
    , R.F_AMOUNT As [Original F_AMOUNT]
    , Case R.F_AMOUNT
        When 0 Then R1.F_DATE
        Else R.F_DATE
        End As F_DATE
    , Case R.F_AMOUNT
        When 0 Then R1.F_AMOUNT
        Else R.F_AMOUNT
        End As F_AMOUNT
From RnkItems As R
    Left Join RnkItems As R1
        On R1.Rnk = R.Rnk + 1

SQL小提琴版本

如果您使用的是 SQL Server 2012,则可以使用新的Lead函数:

Select B_ID, P_DATE, P_AMOUNT
    , F_DATE As [Original F_DATE]
    , F_AMOUNT As [Original F_AMOUNT]
    , Case F_AMOUNT 
        When 0 Then Lead ( F_DATE, 1 ) Over ( Order By F_DATE )
        Else F_DATE
        End As F_DATE
    , Case F_AMOUNT 
        When 0 Then Lead ( F_AMOUNT, 1 ) Over ( Order By F_DATE )
        Else F_AMOUNT
        End As F_AMOUNT
From SourceData

SQL小提琴版本

上述两种解决方案依赖于您总是提前一个月的规定要求。但是,如果您想在一个月使用非零值(即,它可能是多次跳跃),那就不同了:

Select S.B_ID, S.P_DATE, S.P_AMOUNT
    , S.F_DATE As [Original F_DATE]
    , S.F_AMOUNT As [Original F_AMOUNT]
    , Case S.F_AMOUNT
        When 0 Then (
                    Select Min( S2.F_DATE )
                    From SourceData As S2
                    Where S2.F_DATE >= S.F_DATE
                        And S2.F_AMOUNT <> 0
                    )
        Else S.F_DATE
        End As F_DATE
    , Case S.F_AMOUNT
        When 0 Then (
                    Select S1.F_AMOUNT
                    From SourceData As S1
                    Where S1.F_DATE =   (
                                        Select Min( S2.F_DATE )
                                        From SourceData As S2
                                        Where S2.F_DATE > S.F_DATE
                                            And S2.F_AMOUNT <> 0
                                        )
                    )
        Else S.F_AMOUNT
        End As F_AMOUNT
From SourceData As S

SQL小提琴版本

于 2013-09-23T22:16:51.210 回答
0

使用 Forecast 表的嵌套选择,以便在具有值的生产日期之后获得最小预测日期,例如:

SELECT MIN(F1.F_DATE) 
WHERE F1.F_DATE > P1.P_DATE 
    AND F1.F_AMOUNT > 0
于 2013-09-23T21:31:14.810 回答