我有一张桌子(让我们称之为DiodeSales)告诉我我制作的二极管销售总数,按日期,二极管颜色和国家分组。这是此架构的示例:
Date Color Country Sales June, 20 2016 00:00:00 Green US 1 June, 20 2016 00:00:00 Red Japan 1 June, 20 2016 00:00:00 Red US 1 June, 21 2016 00:00:00 Red US 1 June, 22 2016 00:00:00 Green US 1 June, 22 2016 00:00:00 Red US 1 June, 23 2016 00:00:00 Green US 1 June, 23 2016 00:00:00 Red Japan 1 June, 23 2016 00:00:00 Red US 1 June, 24 2016 00:00:00 Green US 1 June, 24 2016 00:00:00 Red US 1
我希望能够有一个额外的列,告诉我在此之前我们已售出多少二极管。因此,例如,使用上述数据,{6月23日,红色,1,美国}行的总销售额将为4,因为我们此时已在美国销售了4个红色二极管。
我最初认为累积金额可以解决问题。所以我写了这个:( sqlfiddle here)
SELECT
t1.Date,
t1.Color,
t1.Country,
t1.Sales,
SUM(t2.Sales) AS CumulativeSales
FROM DiodeSales AS t1
INNER JOIN DiodeSales AS t2
ON t1.Date >= t2.Date
AND t1.Color = t2.Color
AND t1.Country = t2.Country
GROUP BY
t1.Date,
t1.Color,
t1.Country
这给了我累积的金额,如预期的那样,但它没有给出给定日期某个国家给定颜色的总销售额。特别是,由于某些特定日期在某些国家/地区可能有0个销售额,因此它们不会具有与之关联的累计值。例如,考虑上表的结果:
Date Color Country Sales CumulativeSales June, 20 2016 00:00:00 Green US 1 1 June, 20 2016 00:00:00 Red Japan 1 1 June, 20 2016 00:00:00 Red US 1 1 June, 21 2016 00:00:00 Red US 1 2 June, 22 2016 00:00:00 Green US 1 2 June, 22 2016 00:00:00 Red US 1 3 June, 23 2016 00:00:00 Green US 1 3 June, 23 2016 00:00:00 Red Japan 1 2 June, 23 2016 00:00:00 Red US 1 4 June, 24 2016 00:00:00 Green US 1 4 June, 24 2016 00:00:00 Red US 1 5
如果我在6月24日找到与日本相对应的专栏,我什么也没找到(因为当天没有日本特卖,所以那天没有日本排)。我认为在SQL中没有办法做到这一点,但是有可能在这个结果表中填充某些国家没有销售日期的值吗?对于某个国家/地区,起始表每天至少会有一列。
我知道我可以写一个简单的
SELECT SUM(Sales) FROM DiodeSales WHERE Date <= @someDate AND Color = @someColor AND Country = @someCountry
获取此信息,但这是针对一个必须以这种方式格式化的表,以供其他已经制作的软件使用。
编辑:有人提到这是计算Running Total in SQL Server的潜在副本,但该帖子仅在计算运行总和时解决了效率问题。我已经有各种方法来计算这笔钱,但我正在寻找一种方法来解决在该国没有销售的日子里缺少日/国家组合的问题。对于上面的示例,固定查询将返回以下内容:
Date Color Country Sales CumulativeSales June, 20 2016 00:00:00 Green US 1 1 June, 20 2016 00:00:00 Red Japan 1 1 June, 20 2016 00:00:00 Red US 1 1 June, 21 2016 00:00:00 Green US 0 1 June, 21 2016 00:00:00 Red Japan 0 1 June, 21 2016 00:00:00 Red US 1 2 June, 22 2016 00:00:00 Green US 1 2 June, 22 2016 00:00:00 Red Japan 0 1 June, 22 2016 00:00:00 Red US 1 3 June, 23 2016 00:00:00 Green US 1 3 June, 23 2016 00:00:00 Red Japan 1 2 June, 23 2016 00:00:00 Red US 1 4 June, 24 2016 00:00:00 Green US 1 4 June, 24 2016 00:00:00 Red Japan 0 2 June, 24 2016 00:00:00 Red US 1 5
答案 0 :(得分:3)
试试这个:
SELECT [Date], Color, Country, Sales,
SUM(Sales) OVER(PARTITION BY Color, Country ORDER BY [Date] rows unbounded preceding) as RunningTotal
FROM YourTable
ORDER BY [Date], Color
按预期生成输出。
<强> [编辑] 强>
如果您正在寻找缺少日期,国家/地区和颜色的解决方案,请尝试此操作(将@tmp
替换为您的表格名称):
SELECT A.[Date], A.Color, A.Country, COALESCE(B.Sales, 0) AS Sales
, SUM(COALESCE(B.Sales, 0)) OVER(PARTITION BY A.Color, A.Country ORDER BY A.[Date] rows unbounded preceding) as RunningTotal
FROM (
SELECT [Date], Color, Country
FROM (SELECT DISTINCT [Date] FROM @tmp) AS q1 CROSS JOIN
(SELECT DISTINCT Color FROM @tmp) AS q2 CROSS JOIN
(SELECT DISTINCT Country FROM @tmp) AS q3
) AS A
LEFT JOIN @tmp AS B ON A.[Date] = B.[Date] AND A.Color= B.Color AND A.Country = B.Country
ORDER BY A.[Date], A.Color
以上查询产生:
Date Color Country Sales RunningTotal
2016-06-20 Green Japan 0 0
2016-06-20 Green US 1 1
2016-06-20 Red Japan 1 1
2016-06-20 Red US 1 1
2016-06-21 Green US 0 1
2016-06-21 Green Japan 0 0
2016-06-21 Red US 1 2
2016-06-21 Red Japan 0 1
2016-06-22 Green Japan 0 0
2016-06-22 Green US 1 2
2016-06-22 Red Japan 0 1
2016-06-22 Red US 1 3
2016-06-23 Green US 1 3
2016-06-23 Green Japan 0 0
2016-06-23 Red US 1 4
2016-06-23 Red Japan 1 2
2016-06-24 Green Japan 0 0
2016-06-24 Green US 1 4
2016-06-24 Red Japan 0 2
2016-06-24 Red US 1 5
答案 1 :(得分:2)
我认为你应该使用左连接而不是内连接
SELECT
t.Date,
t.Color,
t.Country,
t.CumulativeSales
from DiodeSales t
left join
(SELECT
t1.Date,
t1.Color,
t1.Country,
t1.Sales,
SUM(t2.Sales) AS CumulativeSales
FROM DiodeSales AS t1
GROUP BY
t1.Date,
t1.Color,
t1.Country) t2
on
t.Date=t2.date
and t.Color=t2.color
and t.Country=t2.country
答案 2 :(得分:0)
试试这个
Select distinct Date into SalesDate From DiodeSales
SELECT S.Date,t.Color,t.Country,t.CumulativeSales
from DiodeSales t left join
(SELECt t1.Date,t1.Color,t1.Country,t1.Sales,
SUM(t2.Sales) AS CumulativeSales FROM DiodeSales AS t1
GROUP BY
t1.Date,
t1.Color,
t1.Country) t2 on
S.Date=t2.date
and t.Color=t2.color
and t.Country=t2.country
join
SalesDate S
on t.date=S.date