对不起,如果标题没有做到这个问题正义,但请推荐一个新标题,如果你有一个更好的。
我需要完成的是我需要根据RecDates之间的范围获取QtyOnHand(对于给定的AffectedDate)/ sum(IssQty)。因此,如果AffectedDate ='2015-2',那么我想要将RecDate在'2014-2'和'2015-1'之间的所有IssQty相加。我希望每个AffectedDate行都有这种类型的公式。因此它可以即时计算,这意味着它将始终采用AffectedDates年和月和-12,然后根据RecDate将IssQty加在一起。这里有些例子。
ItemKey RecDate IssQty AffectedDate QtyOnHand
20406 2014-1 751.898 2014-1 842.132
20406 2014-2 744.102 2014-2 539.03
20406 2014-5 493.847 2014-5 486.183
20406 2014-7 494.834 2014-7 1314.209
20406 2014-8 494.217 2014-8 819.992
20406 2014-9 741.017 2014-9 1401.975
20406 2014-10 889.714 2014-10 512.261
20406 2014-12 740.647 2014-12 640.19
20406 2015-2 496.068 2015-2 144.122
20406 2015-3 496.068 2015-3 530.054
20406 2015-5 370.941 2015-5 159.113
20406 2015-7 989.668 2015-7 492.19
20406 2015-8 792.228 2015-8 890.662
20406 2015-9 744.102 2015-9 1028.56
AffectedDate ='2015-3'所以请在'2014-03'和'2015-02'的RecDate之间获取该AffectedDate [530.054] / Sum(IssQty)的QtyOnHand
AffectedDate ='2015-5'所以请在'2014-05'和'2015-04'的RecDate之间获取该AffectedDate [159.113] / Sum(IssQty)的QtyOnHand
这些是我希望这个公式如何工作的例子。
答案 0 :(得分:1)
好的,让我们首先从基础开始。就像Bertrand先生说2014-1
不是约会对象一样,它看起来就像你在说" 2014减去1" (2013年)。我认为它真正意味着代表的是2014年的第一个月,但是,如果您想存储日期,请将它们存储为date
。你会注意到CONVERT(date,'2014-1
)会失败。
我不打算将这些值转换为日期,但我有必要在我的示例数据中执行此操作;也许那会帮助你。
CREATE TABLE #Sample (ItemKey int,
RecDate date, --The source data is not a date
IssQty decimal(10,3),
AffectedDate date, --The sourse data is not a date
QtyOnHand decimal(10,3));
INSERT INTO #Sample
SELECT ItemKey,
CONVERT(date,CASE LEN(RecDate) WHEN 6 THEN STUFF(RecDate,5,1,'0') + '01'
WHEN 7 THEN REPLACE(RecDate,'-','') + '01' END),
IssQty,
CONVERT(date,CASE LEN(AffectedDate) WHEN 6 THEN STUFF(AffectedDate,5,1,'0') + '01'
WHEN 7 THEN REPLACE(AffectedDate,'-','') + '01' END),
QtyOnHand
FROM (VALUES (20406,'2014-1',751.898,'2014-1',842.132 ),
(20406,'2014-2',744.102,'2014-2',539.03 ),
(20406,'2014-5',493.847,'2014-5',486.183 ),
(20406,'2014-7',494.834,'2014-7',1314.209 ),
(20406,'2014-8',494.217,'2014-8',819.992 ),
(20406,'2014-9',741.017,'2014-9',1401.975 ),
(20406,'2014-10',889.714,'2014-10',512.261),
(20406,'2014-12',740.647,'2014-12',640.19 ),
(20406,'2015-2',496.068,'2015-2',144.122 ),
(20406,'2015-3',496.068,'2015-3',530.054 ),
(20406,'2015-5',370.941,'2015-5',159.113 ),
(20406,'2015-7',989.668,'2015-7',492.19 ),
(20406,'2015-8',792.228,'2015-8',890.662 ),
(20406,'2015-9',744.102,'2015-9',1028.56 )) V(ItemKey, RecDate, IssQty, AffectedDate, QtyOnHand);
接下来,我们在这里错过了几个月,这是一个问题,因为您想要过去12个月的数据。因此,我们需要填写这些内容。我将使用日历表(您需要谷歌这一点,在这里我的名为DimDate)。
然后,因为我们有每行的记录,我们可以使用ROWS BETWEEN
导致:
WITH MaxMin AS(
SELECT ItemKey, MIN(AffectedDate) AS MinDate, MAX(AffectedDate) AS MaxDate
FROM #Sample
GROUP BY ItemKey),
WithNewColumn AS(
SELECT MM.ItemKey,
S.RecDate,
S.IssQty,
DD.[Date] AS AffectedDate,
S.QtyOnHand,
S.QtyOnHand / SUM(S.IssQty) OVER (PARTITION By MM.ItemKey ORDER BY DD.[Date]
ROWS BETWEEN 13 PRECEDING AND 1 PRECEDING) AS YourNewColumn
FROM MaxMin MM
JOIN DimDate DD ON DD.[Date] BETWEEN MM.MinDate AND MM.MaxDate AND DD.[Calendar Day] = 1
LEFT JOIN #Sample S ON MM.ItemKey = S.ItemKey
AND DD.[Date] = S.AffectedDate)
SELECT *
FROM WithNewColumn
WHERE RecDate IS NOT NULL --eliminate the NULLs (if you want to). if not, this isn't needed, nor the CTE above
ORDER BY ItemKey, AffectedDate;
答案 1 :(得分:0)
如果您的日期没有空白,则只能使用一个sum
窗口功能解决您的问题。所以你需要自我加入。以下是使用apply
select
*, a.QtyOnHand / c.total
from
myTable a
outer apply (
select
total = sum(IssQty)
from
myTable b
where
b.RecDate between dateadd(mm, -12, a.AffectedDate) and dateadd(mm, -1, a.AffectedDate)
) c