在CTE中对日期范围内的列求和?

时间:2016-04-12 16:51:34

标签: sql function aggregate common-table-expression

我试图在某个日期范围内对某列进行求和。踢球者是我希望这是一个CTE,因为作为更大的查询的一部分,我将不得不多次使用它。由于它是CTE,它必须有日期列以及sum和ID列,这意味着我必须按日期和ID进行分组。这将导致我的结果按ID和日期分组,不是给我一个日期范围的总和,而是一堆总和,每天一个。

为了简单起见,我们说:

create table orders (  
 id int primary key,  
 itemID int foreign key references items.id,  
 datePlaced datetime,  
 salesRep int foreign key references salesReps.id,  
 price int,  
 amountShipped int);

现在,我们希望获得按财务年度分列的特定销售代表的总金额。也就是说,忽略财政年度位:

select itemName, sum(price) as totalSales, sum(totalShipped) as totalShipped
 from orders
 join items on items.id = orders.itemID
 where orders.salesRep = '1234'
 group by itemName

足够简单。但是当你添加任何其他东西,甚至是价格时,查询会吐出比你想要的更多的行。

    select itemName, price, sum(price) as totalSales, sum(totalShipped) as totalShipped
     from orders
 join items on items.id = orders.itemID
 where orders.salesRep = '1234'
 group by itemName, price

现在,每个组都是(名称,价格)而不是(名称)。这是一种sudocode,但在我的数据库中,只是这个更改导致我的结果集从13行跳到32行。添加到日期范围,你真的有一个问题:

select itemName, price, sum(price) as totalSales, sum(totalShipped) as totalShipped  
 from orders  
 join items on items.id = orders.itemID  
 where orders.salesRep = '1234'  
  and orderDate between 150101 and 151231  
 group by itemName, price  

这与上一个例子相同。麻烦在于它成为CTE:

with totals as (  
 select itemName, price, sum(price) as totalSales, sum(totalShipped) as totalShipped, orderDate as startDate, orderDate as endDate  
  from orders  
   join items on items.id = orders.itemID  
  where orders.salesRep = '1234'  
   and orderDate between startDate and endDate  
 group by itemName, price, startDate, endDate  
)  
select totals_2015.itemName as itemName_2015, totals_2015.price as price_2015, ...  
 totals_2016.itemName as itemName_2016, ...  
 from (  
 select * from totals  
 where startDate = 150101 and endDate = 151231  
) totals_2015  
 join (  
 select *  
 from totals  
 where startDate = 160101 and endDate = 160412  
) totals_2016  
on totals_2015.itemName = totals_2016.itemName  

现在,CTE的分组已经过时了,而不仅仅是增加价格。我已经考虑过将价格查询分解为CTE中自己的子查询,但我无法逃避需要按日期分组才能获得日期范围。任何人都可以看到这个方法吗?我希望我已经说清楚了。这是针对IBM iSeries机器运行的。谢谢!

3 个答案:

答案 0 :(得分:0)

根据您的要求,这可能是更好的方法:

fName = (FirstName + "..").subString(0,2);

答案 1 :(得分:0)

当id列或外键可能分组时,因为列已经被索引,你将获得更快的结果。这适用于任何数据库。

with cte as (
select id,rep, sum(sales) sls, count(distinct itemid) did, count(*) cnt from sommewhere 
where date between x and y
group by id,rep
) select * from cte order by rep

或更多花哨

with cte as (
select id,rep, sum(sales) sls, count(distinct itemid) did, count(*) cnt from sommewhere 
where date between x and y
group by id,rep
) select * from cte join reps on cte.rep = reps.rep order by sls desc

答案 2 :(得分:0)

我最终找到了一个解决方案,它根本不需要CTE。我希望CTE避免代码重复,但这几乎也可以。这是一个https://itunes.apple.com/us/app/sketchfab/id1201268000?mt=8,完全符合我的要求。