首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用案例何时从不同行的条件填充?

使用案例何时从不同行的条件填充?
EN

Stack Overflow用户
提问于 2017-04-17 22:11:19
回答 1查看 58关注 0票数 1

我在SQL中使用CASE WHENs来根据每个组中不同的计算标准计算一个新列。随着时间的推移,每个帐户的数据都会通过一系列组流动--大部分时间都在增加,但在的情况下,它可以保持不变甚至减少。

以下是我的数据和计算的简化示例:

代码语言:javascript
运行
复制
======================================
|     ------ SAMPLE TABLE ------     |
======================================
| ACCT | MONTH | GROUP | VAL1 | VAL2 | 
--------------------------------------
|   A  |  Jan  |   1   |   2  |   5  |
|   A  |  Feb  |   2   |   4  |   9  |
|   A  |  Mar  |   3   |   5  |  10  |
|   B  |  Jan  |   1   |  10  |  15  |
|   B  |  Feb  |   2   |   6  |   9  |
|   B  |  Mar  |   2   |  10  |   8  |
|   B  |  Apr  |   3   |   8  |  12  |
|   B  |  May  |   3   |   6  |  11  |
--------------------------------------

==============================================
|       ----- SAMPLE CALCULATIONS -----      |
==============================================
| GROUP = 1: VAL1 + VAL2                     |
| GROUP = 2: VAL1 - VAL2                     |
| GROUP = 3: Output of most recent GROUP = 2 |
----------------------------------------------

我想为所有行计算一个新列(未显示)。注意,GROUP =3的计算标准只是“使用前一组计算输出的最新条目”。虽然可能很容易再次使用组= 2的相同计算公式,但组=3行中的值将有所不同。就账目A及B而言,以下是我所面对的挑战:

帐户A:如何计算组=2中的值,然后将其填充到组= 3中?

帐户B: --这要复杂得多,而且我确实有多个这样的实例。GROUP =3的第一个实例将使用与上面所述A相同的逻辑。但是,对于GROUP = 3的后续实例,它应该返回最新的组=2并复制计算,或者最早的组=3并复制使用A中的方法填充的值(这两种方法仍然应该产生相同的结果)。

希望这是足够清楚的理解。谢谢您的提前,我很高兴回答任何澄清的问题!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-17 23:34:37

您应该避免使用“Jan”、“Feb”等字符串来跟踪日期。您的问题需要及时对记录进行排序,但是如果您在月份字段上执行了排序,则它会将其排序为字符串(即'Feb‘、'Jan’、'Mar')。此外,您应该记录确切的日期,而不仅仅是月份,否则您无法保证在多年内准确的时间订购。

尽管如此,有几种不同的方法可以做到这一点,这是我认为非常酷的一种。首先,您需要加入ACCT上的记录,其中左表组为3,右表是最新的非组3数据。此查询:

代码语言:javascript
运行
复制
select
          a1.ACCT
        , DATEPART(MM, a1.Mnth + ' 1 2017') as Mnth -- see what a pain it is to use strings instead of dates?
        , a1.Grp
        , a1.Val1
        , a1.Val2
        , a2.ACCT
        , DATEPART(MM, a2.Mnth + ' 1 2017') as Mnth
        , a2.Grp
        , a2.Val1
        , a2.Val2
    from #A a1
    outer apply (
        select top 1 *
            from #A
            where ACCT = a1.ACCT -- match on the account
                and Grp < 3
                and a1.Grp = 3 -- I'll explain at the end why we don't actually need this
                and DATEPART(MM, Mnth + ' 1 2017') < DATEPART(MM, a1.Mnth + ' 1 2017') -- grab all previous dates
            order by DATEPART(MM, Mnth + ' 1 2017') desc -- grab the latest previous date (along with the top command)

    ) as a2
    order by  a1.ACCT
            , DATEPART(MM, a1.Mnth + ' 1 2017')

产生下表:

代码语言:javascript
运行
复制
+ ---- + ---- + --- + ---- + ---- + ---- + ---- + ---- + ---- + ---- +
| ACCT | Mnth | Grp | Val1 | Val2 | ACCT | Mnth | Grp  | Val1 | Val2 |
+ ---- + ---- + --- + ---- + ---- + ---- + ---- + ---- + ---- + ---- +
| A    | 1    | 1   | 2    | 5    | NULL | NULL | NULL | NULL | NULL |
| A    | 2    | 2   | 4    | 9    | NULL | NULL | NULL | NULL | NULL | 
| A    | 3    | 3   | 5    | 10   | A    | 2    | 2    | 4    | 9    | 
| B    | 1    | 1   | 10   | 15   | NULL | NULL | NULL | NULL | NULL | 
| B    | 2    | 2   | 6    | 9    | NULL | NULL | NULL | NULL | NULL | 
| B    | 3    | 2   | 10   | 8    | NULL | NULL | NULL | NULL | NULL | 
| B    | 4    | 3   | 8    | 12   | B    | 3    | 2    | 10   | 8    | 
| B    | 5    | 3   | 6    | 11   | B    | 4    | 3    | 8    | 12   |
+ ---- + ---- + --- + ---- + ---- + ---- + ---- + ---- + ---- + ---- +

注意所有的第3组记录是如何在正确的表中有数据的,而组1和2的记录都是空的。让我们利用这个事实来进行计算。修改查询:

代码语言:javascript
运行
复制
select
          a1.ACCT
        , DATEPART(MM, a1.Mnth + ' 1 2017') as Mnth -- see what a pain it is to use strings instead of dates?
        , a1.Grp
        , a1.Val1
        , a1.Val2
        , (case a1.GRP when 1 then a1.Val1 + a1.Val2
                       when 2 then a1.Val1 - a1.Val2
                       when 3 then (case a2.Grp when 1 then a2.Val1 + a2.Val2
                                                when 2 then a2.Val1 - a2.Val2
                        end)
        end) as Calculation
    from ... -- same as above

这给了我们希望的结果:

代码语言:javascript
运行
复制
+ ---- + ---- + --- + ---- + ---- + ----------- + 
| ACCT | Mnth | Grp | Val1 | Val2 | Calculation |
+ ---- + ---- + --- + ---- + ---- + ----------- + 
| A    | 1    | 1   | 2    | 5    | 7           | 
| A    | 2    | 2   | 4    | 9    | -5          |
| A    | 3    | 3   | 5    | 10   | -5          | 
| B    | 1    | 1   | 10   | 15   | 25          | 
| B    | 2    | 2   | 6    | 9    | -3          |  
| B    | 3    | 2   | 10   | 8    | 2           | 
| B    | 4    | 3   | 8    | 12   | 2           | 
| B    | 5    | 3   | 6    | 11   | 2           | 
+ ---- + ---- + --- + ---- + ---- + ----------- +

请注意,我们不需要行and a1.Grp = 3,因为我们编写case语句的方式。去掉那条线,你就会看到我们得到了同样的结果。

希望这能有所帮助!

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43460455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档