我在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
答案 0 :(得分:0)
使用预测表的嵌套选择,以便在生产日期之后获得具有值的最小预测日期,例如:
SELECT MIN(F1.F_DATE)
WHERE F1.F_DATE > P1.P_DATE
AND F1.F_AMOUNT > 0
答案 1 :(得分: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 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
以上两种解决方案依赖于规定的要求,即您总是要提前一个月。但是,如果您希望第一个月具有非零值(即,它可能是多次跳转),那就不同了:
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