如何在SQL Server的第二列基础上的两列中显示一列

时间:2013-12-24 08:25:31

标签: sql sql-server

我有一个表sales,其中包含

Month   SalesAmount
--------------------------
4   50000
5   60000
6   70000
7   50000
8   60000
9   40000

我想要这样的结果

From Month  To Month    Result 
-----------------------------------------------
4                  6    Increasing
6                  7    Decreasing
7                  8    Increasing
8                  9    Decreasing

不使用光标

3 个答案:

答案 0 :(得分:2)

试试这个。基本上,您需要按月(+1)将表连接到自身,然后提取您想要的数据/执行任何计算。

Select 
    M1.Month as [From],
    M2.Month as [To],
    Case
        When M2.SalesAmount > M1.SalesAmount Then 'Increasing'
        When M2.SalesAmount < M1.SalesAmount Then 'Decreasing'
        Else 'Holding Steady'
    End
From sales M1
    Inner Join sales M2 on M2.Month = M1.Month + 1

如果您希望按月分类,则此方法有效。但是,您的示例数据集会压缩4-6个月。如果没有关于如何确定压缩内容的更多细节,我将做出以下假设:

  • 您需要过去3个时段的详细数据,以及所有其他时段的压缩摘要。
  • 您只希望压缩期内第一个月和最后一个月之间的整体趋势。即你想知道第一个和上个月价值之间的差异。

为此,查询开始变得更复杂。我用两个Unioned查询完成了它:

With 
compressed_range as
( select min([Month]) as min_month, max([Month]) - 3 as max_month from sales )
Select 
    M1.[Month] as [From], 
    M2.[Month] as [To],
    Case
        When M2.SalesAmount > M1.SalesAmount Then 'Increasing'
        When M2.SalesAmount < M1.SalesAmount Then 'Decreasing'
        Else 'Holding Steady'
    End
From sales M1 
    Inner Join sales M2 on M2.[Month] = ( select max_month from compressed_range )
Where M1.Month = ( select min_month from compressed_range )
Union All
Select 
    M1.Month as [From],
    M2.Month as [To],
    Case
        When M2.SalesAmount > M1.SalesAmount Then 'Increasing'
        When M2.SalesAmount < M1.SalesAmount Then 'Decreasing'
        Else 'Holding Steady'
    End
From sales M1
    Inner Join sales M2 on M2.Month = M1.Month + 1
Where M2.Month >= (Select max_month + 1 from compressed_range)

答案 1 :(得分:0)

这会得到您想要的结果:

DECLARE @T TABLE (Month INT, SalesAmount MONEY);
INSERT @T
VALUES (4, 50000), (5, 60000), (6, 70000), (7, 50000), (8, 60000), (9, 40000);

WITH CTE AS
(   SELECT  FromMonth = T2.Month,
            ToMonth = T.Month,
            Result = CASE T2.Result
                        WHEN -1 THEN 'Decreasing'
                        WHEN 0 THEN 'Static'
                        WHEN 1 THEN 'Increasing'
                    END,
            GroupingSet = ROW_NUMBER() OVER(ORDER BY T.Month) - ROW_NUMBER() OVER(PARTITION BY T2.Result ORDER BY T.Month)
    FROM    @T T
            CROSS APPLY
            (   SELECT  TOP 1 
                        T2.SalesAmount, 
                        T2.Month,
                        Result = SIGN(T.SalesAmount - T2.SalesAmount)
                FROM    @T T2
                WHERE   T2.Month < T.Month
                ORDER BY T2.Month DESC
            ) T2
)
SELECT  FromMonth = MIN(FromMonth),
        ToMonth = MAX(ToMonth),
        Result
FROM    CTE
GROUP BY Result, GroupingSet
ORDER BY FromMonth;

第一阶段是每次获得上个月的销售额:

SELECT  *
FROM    @T T
        CROSS APPLY
        (   SELECT  TOP 1 
                    T2.SalesAmount, 
                    T2.Month,
                    Result = SIGN(T.SalesAmount - T2.SalesAmount)
            FROM    @T T2
            WHERE   T2.Month < T.Month
            ORDER BY T2.Month DESC
        ) T2
ORDER BY T.MONTH

将给予:

Month   SalesAmount SalesAmount Month   Result
5       60000.00    50000.00    4       1.00
6       70000.00    60000.00    5       1.00
7       50000.00    70000.00    6       -1.00
8       60000.00    50000.00    7       1.00
9       40000.00    60000.00    8       -1.00

结果只是指示金额是增加还是减少的指标。然后,您需要应用一个排序技巧,即序列中的每个成员 - 它在序列中的位置对于顺序成员是不变的。因此,如果我们添加了以上数据集:

RN1 = ROW_NUMBER() OVER(ORDER BY T.Month),
RN2 = ROW_NUMBER() OVER(PARTITION BY T2.Result ORDER BY T.Month)

Month   SalesAmount SalesAmount Month   Result  RN1 RN2 | RN1 - RN2
5       60000.00    50000.00    4       1.00    1   1   |     0
6       70000.00    60000.00    5       1.00    2   2   |     0
7       50000.00    70000.00    6       -1.00   3   1   |     2
8       60000.00    50000.00    7       1.00    4   3   |     1
9       40000.00    60000.00    8       -1.00   5   2   |     3

因此,您可以看到前两行的最后一列RN1 - RN2保持不变,因为它们都在增加,然后当结果发生变化时,这两个row_numbers chnages之间的差异,因此会创建一个新的组。 / p>

然后,您可以按此计算(原始查询中的GroupingSet列)进行分组,以便将连续的增加和减少时段分组。

<强> Example on SQL Fiddle

答案 2 :(得分:0)

如果您在表格结构中仅使用了月份,则可以尝试这样的

SELECT s1.month AS From_Month, 
       s2.month AS To_Month, 
       CASE 
         WHEN s2.salesamount > s1.salesamount THEN 'Increasing' 
         ELSE 'Decresing' 
       END      AS res 
FROM   sales AS s1, 
       sales AS s2 
WHERE  s1.month + 1 = s2.month 

演示http://sqlfiddle.com/#!6/0819d/11