0

我有一张桌子:

SourceID、TargetID、金额、年份。

我也有看法。此视图正在查看同一表中的行和其上方的行之间的差异。我使用 CTE 来做到这一点:

    WITH cte as (SELECT ROW_NUMBER() OVER 
(PARTITION BY SourceID ORDER BY ... ) as rowNum, 
SourceId, TargetID, Amount, Year FROM table)

    Select 
    t1.SourceID as SourceID1, 
t2.SourceID as SourceID2, 
t1.TargetID as TargetID1, 
t2.TargetID as TargetID2, 
t1.Year, 
(t1.Amount - t2.Amount) as Difference

    FROM cte t1
    LEFT JOIN cte t2 ON t1.SourceID = t2.SourceID and t1.rowNum = t2.rowNum+1 

我现在在该视图中有 2 列。目标 ID1 和目标 ID2。TargetID2 与上一行中的 TargetID1 相同。有时 TargetID2 为空,因为在上面显示的左连接中不满足条件。没事儿。从这个视图中选择 * 正是我所需要的。

这里的问题是当我想有条件地选择时。例如:我只想选择以 2012 为年份的行。当然从技术上讲这不是问题,但是当 2012 年的第一行将自己与 2011 年的(现在不可见的)最后一行进行比较时,客户会感到困惑。当结果集中的第一行满足连接条件时,他们希望差异为空(NULL)。

所以我写了这个:

SELECT
    SourceID1, SourceID2, TargetID1, TargetID2, Year,
    case when TargetID2 is null
    then null
    else case when TargetID2 NOT IN (
        select TargetID1 from view where Year = 2012)
    then null
    else Difference
    end
    end as Difference,
FROM view where Year = 2012

这实际上奏效了......它花了一点时间,因为它是一张相当大的桌子,但它是可以接受的。现在我们添加一个百分比(百分比的差异)。这意味着最后一个查询被另一个条件选择扩展,检查完全相同的条件。

case when TargetID2 is null
   then null
   else case when TargetID2 NOT IN (
    select TargetID1 from view where Year = 2012)
   then null
   else Percentage
   end
   end as Percentage

所以这变得非常消耗。

我的问题是:我该怎么办?一般来说,对解决方案、视图或查询的更改都很好。只要过滤结果显示第一行的差异和百分比为空并且查询执行,则没有任何限制。

对不起,大帖子。不知道还能怎么放这个。

谢谢

编辑:

我对问题不够清楚。如果 Year 是唯一的问题,我可以做以下一些建议,但事实并非如此。我简化了表格和视图,使其更具可读性,但还有其他列和其他可以过滤的内容。

还有一个月的专栏。因此,如果我想查看 2011 年 10 月 - 2012 年 2 月,那么 2011 年的最后一行应该与 2012 年的第一行进行比较。这里 10 月的第一行应该有 NULL 差异和百分比列,因为它的 TargetID2 在 TargetID1 中不存在柱子...

我希望这能清除它。也许我应该从头开始回答这个问题。

4

2 回答 2

1

似乎您永远不想将一年的一行与前一年的一行进行比较。如果是这种情况,您应该添加AND t1.Year = t2.Year到视图中的连接条件。

如果这是不正确的并且不知何故 2012 年是一个特殊的年份,您可以将该t2.Year列添加到视图中。这样您就可以直接使用它,而不必加入重新发现它。

于 2013-03-11T13:05:27.383 回答
0

嗯,这似乎比我想象的更难解释。我决定使用我以前的解决方案,但将所有内容都放在存储过程中,而不是视图 + 查询中。这样它就不必多次迭代同一个表。感谢大家的支持!

于 2013-03-13T12:21:31.213 回答