随着时间的推移遇到递归SQL的问题

时间:2016-01-19 20:47:42

标签: sql sql-server join recursion

我正在改写我们的内部金融系统之一。我正在设置的是这个新系统每个月拍摄订单表的快照和快照的日期。这部分效果很好。

下一步是我创建一个视图,其中包含每个月的总计,以及上个月的总计。

当我按团队和月份进行总计时,我设置递归没有问题。我只是在团队中进行自然加入,而月份=月份1(我为该月设置了一个单独的表格,以便让生活更轻松)

我遇到问题的地方是,如果我尝试在加入的同时进行递归。我正在加入团队和月份,但由于某种原因,我最终会加入交叉联盟。有没有理由看到导致交叉连接的原因?有没有人在我的逻辑中看到错误? 这是加入:

select SH1.month, SH1.Team,
   sum(SH2.Monthly_SAMT) as BilledPrevious, sum(SH1.Monthly_SAMT) as BilledCurrent,
   sum(SH1.Monthly_SAMT) - sum(SH2.MonthlyAnnualized_SAMT) BILLEDDIFF
from vw_SalesMonthly2 SH1 full outer join vw_SalesMonthly2 SH2
   on SH1.team=SH2.team and SH1.month_index-1 = SH2.month_index
group by SH1.month, SH1.Team
order by 1 desc, 2 asc

2 个答案:

答案 0 :(得分:1)

我认为你可以在这里使用OUTER APPLY来获得之前的总和。

SELECT  SH1.month,
        SH1.Team,
        COALESCE(SH2.Monthly_SAMT,0) AS BilledPrevious,
        SUM(SH1.Monthly_SAMT) AS BilledCurrent,
        SUM(SH1.Monthly_SAMT) - COALESCE(SH2.MonthlyAnnualized_SAMT,0) BILLEDDIFF
FROM    vw_SalesMonthly2 SH1
        OUTER APPLY (SELECT SUM(SH2.Monthly_SAMT) Monthly_SAMT,
                            SUM(SH2.MonthlyAnnualized_SAMT) MonthlyAnnualized_SAMT
                     FROM   vw_SalesMonthly2 SH2
                     WHERE  SH1.team = SH2.team
                            AND SH1.month_index - 1 = SH2.month_index
                    ) SH2
GROUP BY SH1.month,
        SH1.Team,
        SH2.Monthly_SAMT,
        SH2.MonthlyAnnualized_SAMT
ORDER BY 1 DESC,
        2 ASC

答案 1 :(得分:0)

您希望在执行联接之前按月汇总所有数据,以获取前几个月的数据。因此,您需要在加入之前进行分组。

另外,我认为你想要一个左连接而不是全外连接。你想要每月/团队一行,如果它存在,每行的前一个月的数据,对吗?

这是一个玩具示例:

declare @sales table (id int identity, team integer, mon integer, value money)
insert @sales (team, mon, value) values 
    (1,1,0),
    (1,2,100),
    (1,3,150),
    (2,1,40),
    (2,2,99)

; with cte as (
    select team, mon, sum(value) [value]
    from @sales
    group by team, mon
)
select s1.team, s1.mon, s1.value, s2.value [previous]
from cte s1
left join cte s2 on s1.team=s2.team and s1.mon=s2.mon+1
order by 1 asc, 2 asc

输出:

team        mon         value                 previous
----------- ----------- --------------------- ---------------------
1           1           0.00                  NULL
1           2           100.00                0.00
1           3           150.00                100.00
2           1           40.00                 NULL
2           2           99.00                 40.00