我在MS SQL Server上有这个表
Customer Month Amount
-----------------------------
Tom 1 10
Kate 1 60
Ali 1 70
Tom 2 50
Kate 2 40
Tom 3 80
Ali 3 20
我希望select能够累积每个月的客户
Customer Month Amount
-----------------------------
Tom 1 10
Kate 1 60
Ali 1 70
Tom 2 60
Kate 2 100
Ali 2 70
Tom 3 140
Kate 3 100
Ali 3 90
注意到Ali没有2个月的数据 凯特没有3个月的数据
我已经完成了,但问题是,对于每个客户缺少的月份,没有数据显示 即凯特必须在第3个月有100个金额 和阿里必须在第二个月有70个金额
declare @myTable as TABLE (Customer varchar(50), Month int, Amount int)
;
INSERT INTO @myTable
(Customer, Month, Amount)
VALUES
('Tom', 1, 10),
('Kate', 1, 60),
('Ali', 1, 70),
('Tom', 2, 50),
('Kate', 2, 40),
('Tom', 3, 80),
('Ali', 3, 20);
select * from @myTable
select
SUM(b.Amount),a.Customer, a.Month
from
@myTable a
inner join
@myTable b
on a.Customer = b.Customer and
a.Month >= b.Month
group by
a.Customer, a.Month
答案 0 :(得分:3)
使用窗口功能
select Customer, Month,
sum(Amount) over (partition by customer order by month) Amount
from table t
因此,您需要某种look up
表,这些表可能与客户有关。
with cte as
(
select * from (
select Customer from table
group by Customer)c
cross join (values (1),(2),(3))a(Months)
) -- look-up table
select c.Customer, c.Months,
sum(t.Amount) over (partition by c.Customer order by c.Months) Amount
from cte c left join table t
on t.Month = c.Months and t.Customer = c.Customer
结果:
Customer Months Amount
Tom 1 10
Kate 1 60
Ali 1 70
Tom 2 60
Ali 2 70
Kate 2 100
Ali 3 90
Kate 3 100
Tom 3 140
答案 1 :(得分:2)
with cte as
(select *
from
(select distinct customer from myTable ) c
cross join ( values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)) t(month))
select cte.customer, cte.month,
sum(myTable.amount) over (partition by cte.customer order by cte.month) as cumamount
from cte left join myTable
on cte.customer = myTable.customer and cte.month = myTable.month
order by cte.month, cte.customer desc
答案 2 :(得分:1)
您是否希望每个月为每位客户获得金额,客户在该月的交易情况如何? 在下面的脚本中,如果您有一个customer表,则可以加入customer表,不需要使用(SELECT DISTINCT Customer FROM @myTable)
declare @myTable as TABLE (Customer varchar(50), Month int, Amount int);
INSERT INTO @myTable(Customer, Month, Amount)
VALUES
('Tom', 1, 10),
('Kate', 1, 60),
('Ali', 1, 70),
('Tom', 2, 50),
('Kate', 2, 40),
('Tom', 3, 80),
('Ali', 3, 20),
('Jack', 3, 90);
SELECT c.Customer,sv.number AS Month ,SUM(CASE WHEN t.Month<=sv.number THEN t.Amount ELSE 0 END ) AS Amount
FROM master.dbo.spt_values AS sv
INNER JOIN (SELECT DISTINCT Customer FROM @myTable) AS c ON 1=1
LEFT JOIN @myTable AS t ON t.Customer=c.Customer
WHERE sv.type='P' AND sv.number BETWEEN 1 AND MONTH(GETDATE())
GROUP BY sv.number,c.Customer
ORDER BY c.Customer,sv.number
---------- Customer Month Amount -------------------------------------------------- ----------- ----------- Ali 1 70 Ali 2 70 Ali 3 90 Jack 1 0 Jack 2 0 Jack 3 90 Kate 1 60 Kate 2 100 Kate 3 100 Tom 1 10 Tom 2 60 Tom 3 140
答案 3 :(得分:1)
试试这个表名是“a”。 使用Cte和子查询的组合。在MSSQL2008R2中试过它
with cte as
(
select * from (
select Customer from a
group by Customer)c
cross join (values (1),(2),(3),(4),(5),(6),(7),(8),(9), (10),(11),(12))a(Months)
)
select Customer,Months,
(select SUM(total) from
(select customer , month , sum(amount)as total from a group by customer,
month) as GroupedTable
where GroupedTable.customer= cte.customer and GroupedTable.month<= cte.Months) as total
from cte
Group by Customer,Months
order by Customer,Months
答案 4 :(得分:1)
试试这个: create table #tmp(Customer VARCHAR(10),[month] INT,Amount INT)
INSERT INTO #tmp
SELECT 'Tom',1,10
union all
SELECT 'Kate',1,60
union all
SELECT 'Ali',1,70
union all
SELECT 'Tom',2,50
union all
SELECT 'Kate',2,40
union all
SELECT 'Tom',3,80
union all
SELECT 'Ali',3,20
;WITH cte1 AS (
SELECT [month], ROW_NUMBER() OVER(order by [month] desc) rn
FROM (SELECT DISTINCT [month] as [month] FROM #tmp) a
)
, cte2 AS (
SELECT customer, ROW_NUMBER() OVER(order by customer desc) rn
FROM (SELECT DISTINCT customer as customer FROM #tmp) b
)
SELECT t2.Customer,t2.[month],ISNULL(t1.Amount,0) As Amount
into #tmp2
from #tmp t1
RIGHT JOIN
(select [month],customer from cte1
cross apply
cte2) t2 ON t1.customer=t2.customer and t1.[month]=t2.[month]
order by t2.[month]
SELECT Customer,[Month] ,SUM (Amount) OVER(partition by customer order by customer ROWS UNBOUNDED PRECEDING ) as Amount
FROM #tmp2
order by [month]
drop table #tmp
drop table #tmp2
答案 5 :(得分:1)
要清楚(在答案Amount和AmountSum中)
DECLARE @myTable TABLE(Customer varchar(50), Month int, Amount int);
INSERT INTO @myTable(Customer, Month, Amount)
VALUES
('Tom', 1, 10),
('Kate', 1, 60),
('Ali', 1, 70),
('Tom', 2, 50),
('Kate', 2, 40),
('Tom', 3, 80),
('Ali', 3, 20);
DECLARE @FullTable TABLE(Customer varchar(50), Month int, Amount int);
INSERT INTO @FullTable(Customer, Month, Amount)
SELECT c.Customer, m.Month, ISNULL(mt.Amount, 0)
FROM (SELECT DISTINCT [Month] FROM @myTable) AS m
CROSS JOIN (SELECT DISTINCT Customer FROM @myTable) AS c
LEFT JOIN @myTable AS mt ON m.Month = mt.Month AND c.Customer = mt.Customer
SELECT t1.Customer, t1.Month, t1.Amount, (t1.Amount + ISNULL(t2.sm, 0)) AS AmountSum
FROM @FullTable AS t1
CROSS APPLY (SELECT SUM(Amount) AS sm FROM @FullTable AS t WHERE t.Customer = t1.Customer AND t.Month < t1.Month) AS t2
ORDER BY Month, Customer
答案 6 :(得分:1)
我认为这可以做你想要的事情
declare @myTable as TABLE (Customer varchar(50), Month int, Amount int);
INSERT INTO @myTable (Customer, Month, Amount)
VALUES
('Tom', 1, 10),
('Kate', 1, 60),
('Ali', 1, 70),
('Tom', 2, 50),
('Kate', 2, 40),
('Tom', 3, 80),
('Ali', 3, 20);
select dts.Month, cts.Customer, isnull(t.Amount, 0) as Amount
, sum(isnull(t.Amount, 0)) over(partition by cts.Customer order by dts.Month) as CumAmt
from ( select distinct customer
from @myTable
) cts
cross join ( select distinct Month
from @myTable
) dts
left join @myTable t
on t.Customer = cts.Customer
and t.Month = dts.Month
order by dts.Month, cts.Customer;
Month Customer Amount CumAmt
----------- -------------------------------------------------- ----------- -----------
1 Ali 70 70
1 Kate 60 60
1 Tom 10 10
2 Ali 0 70
2 Kate 40 100
2 Tom 50 60
3 Ali 20 90
3 Kate 0 100
3 Tom 80 140
答案 7 :(得分:0)
尝试对分区进行求和 https://docs.microsoft.com/en-us/sql/t-sql/functions/sum-transact-sql
这将帮助您了解如何积累。如果我在postgresql中使用的代码是这样的
Select sum(amount) over(partition by customer, month)
答案 8 :(得分:0)
这应该为你做。此处还有指向聚合函数的Microsoft文档的链接。
https://docs.microsoft.com/en-us/sql/t-sql/functions/aggregate-functions-transact-sql
示例:
SELECT
Customer, Month, SUM(Amount) as Amount
FROM myTable
GROUP BY Customer, Month
ORDER BY Customer, Month