Sql 使用Pivot计算最近两天的数据更改百分比

Sql 使用Pivot计算最近两天的数据更改百分比,sql,sql-server,pivot,Sql,Sql Server,Pivot,我有一个表,其中包含每天收集的一组数据(我使用SQL Server 2016) 我正在尝试编写一个查询,该查询将显示最近两天和%的更改,并返回如下结果: Field Today Yesterday Change(%) A 1.1 1.0 10.0% B 2.1 2.0 5.0% C 3.1 3.0 3.3% D 4.1 4.0 2.5%

我有一个表,其中包含每天收集的一组数据(我使用SQL Server 2016)

我正在尝试编写一个查询,该查询将显示最近两天和%的更改,并返回如下结果:

Field  Today   Yesterday  Change(%)
A       1.1       1.0       10.0%
B       2.1       2.0        5.0%
C       3.1       3.0        3.3%
D       4.1       4.0        2.5%

有没有一种快速的方法可以做到这一点(我假设pivot涉及某个地方,但我真的无法解决此查询)

这应该可以满足您的需要:

select
    FieldValue                          as  [Field]
    , case FieldValue 
        when 'A'
            then ta
        when 'B'
            then tb
        when 'C'
            then tc
        when 'D'
            then td
        end                             as  [Today]
    , case FieldValue 
        when 'A'
            then ya
        when 'B'
            then yb
        when 'C'
            then yc
        when 'D'
            then yd
        end                             as  [Yesterday]
    , Change                            as  [Change(%)]
    from
    (select
        t1.a                            as  [ta]    -- today's A value
        , t1.b                          as  [tb]    -- today's B value
        , t1.c                          as  [tc]    -- today's C value
        , t1.d                          as  [td]    -- today's D value
        --, t1.e                        as  [te]    -- today's E value
        -- make sure to include the t1.e, t1.f etc. for other Fields too

        , y.a                           as  [ya]    -- yesterday's A value
        , y.b                           as  [yb]    -- yesterday's B value
        , y.c                           as  [yc]    -- yesterday's C value
        , y.d                           as  [yd]    -- yesterday's D value
        --, y.e                         as  [ye]    -- yesterday's E value
        -- make sure to include the y.e, y.f etc. for other Fields too

        , 100 / (y.a / (t1.a - y.a))    as  [A]     -- A's change since yesterday
        , 100 / (y.b / (t1.b - y.b))    as  [B]     -- B's change since yesterday
        , 100 / (y.c / (t1.c - y.c))    as  [C]     -- C's change since yesterday
        , 100 / (y.d / (t1.d - y.d))    as  [D]     -- D's change since yesterday
        --, 100 / (y.e / t1.e - y.e))   as  [E]     -- E's change since yesterday (INCLUDE this "E" alias in the list of columns from UNPIVOT)
        -- make sure to add calculations for your other fields here too

    from baseTable t1
        cross apply (select top 1 * 
                     from baseTable t2 
                     where t2.date < t1.date) y
    where t1.date = (select max(date) from baseTable)
    ) result
unpivot (
    Change for FieldValue in (a, b, c, d) --, e, f etc.) -- enumerate all column ALIASES used in the sub-select, where the CHANGE is calculated
    ) as unpvt

这将为您提供您需要的:

select
    FieldValue                          as  [Field]
    , case FieldValue 
        when 'A'
            then ta
        when 'B'
            then tb
        when 'C'
            then tc
        when 'D'
            then td
        end                             as  [Today]
    , case FieldValue 
        when 'A'
            then ya
        when 'B'
            then yb
        when 'C'
            then yc
        when 'D'
            then yd
        end                             as  [Yesterday]
    , Change                            as  [Change(%)]
    from
    (select
        t1.a                            as  [ta]    -- today's A value
        , t1.b                          as  [tb]    -- today's B value
        , t1.c                          as  [tc]    -- today's C value
        , t1.d                          as  [td]    -- today's D value
        --, t1.e                        as  [te]    -- today's E value
        -- make sure to include the t1.e, t1.f etc. for other Fields too

        , y.a                           as  [ya]    -- yesterday's A value
        , y.b                           as  [yb]    -- yesterday's B value
        , y.c                           as  [yc]    -- yesterday's C value
        , y.d                           as  [yd]    -- yesterday's D value
        --, y.e                         as  [ye]    -- yesterday's E value
        -- make sure to include the y.e, y.f etc. for other Fields too

        , 100 / (y.a / (t1.a - y.a))    as  [A]     -- A's change since yesterday
        , 100 / (y.b / (t1.b - y.b))    as  [B]     -- B's change since yesterday
        , 100 / (y.c / (t1.c - y.c))    as  [C]     -- C's change since yesterday
        , 100 / (y.d / (t1.d - y.d))    as  [D]     -- D's change since yesterday
        --, 100 / (y.e / t1.e - y.e))   as  [E]     -- E's change since yesterday (INCLUDE this "E" alias in the list of columns from UNPIVOT)
        -- make sure to add calculations for your other fields here too

    from baseTable t1
        cross apply (select top 1 * 
                     from baseTable t2 
                     where t2.date < t1.date) y
    where t1.date = (select max(date) from baseTable)
    ) result
unpivot (
    Change for FieldValue in (a, b, c, d) --, e, f etc.) -- enumerate all column ALIASES used in the sub-select, where the CHANGE is calculated
    ) as unpvt

我会首先使用一个窗口功能,比如
行数
来获取前两个日期,然后将
a
B
C
d
的列取消分割成行,从而得到结果。一旦你完成了这项工作,你就可以将这些结果转化为最终想要的产品

对此进行分解,我将首先使用
行编号

select [Date], A, B, C, D,
  rn = row_number() over(order by [Date] desc) 
from #yourtable
这将为表中的每一行创建一个唯一的行id,您可以按日期对其排序,以生成所需顺序的日期。接下来,您将把
A
B
C
、和
D
列解压成行:

select 
  Field,
  value, 
  Dt = case when rn = 1 then 'Today' else 'Yesterday' end
from
(
  select [Date], A, B, C, D,
    rn = row_number() over(order by [Date] desc) 
  from #yourtable
) x
cross apply
(
  values
  ('A', A),
  ('B', B),
  ('C', C),
  ('D', D)  -- include additional columns here if you have more
) c (Field, value)
where rn <= 2 -- return top 2 dates
这是一本书。这将为您提供以下结果:

Field Today Yesterday ChangePercent 
----- ----- --------- ------------- 
A     1.1   1         10            
B     2.1   2         5             
C     3.1   3         3.33          
D     4.1   4         2.5           

我会首先使用一个窗口功能,比如
行数
来获取前两个日期,然后将
a
B
C
d
的列取消分割成行,从而得到结果。一旦你完成了这项工作,你就可以将这些结果转化为最终想要的产品

对此进行分解,我将首先使用
行编号

select [Date], A, B, C, D,
  rn = row_number() over(order by [Date] desc) 
from #yourtable
这将为表中的每一行创建一个唯一的行id,您可以按日期对其排序,以生成所需顺序的日期。接下来,您将把
A
B
C
、和
D
列解压成行:

select 
  Field,
  value, 
  Dt = case when rn = 1 then 'Today' else 'Yesterday' end
from
(
  select [Date], A, B, C, D,
    rn = row_number() over(order by [Date] desc) 
  from #yourtable
) x
cross apply
(
  values
  ('A', A),
  ('B', B),
  ('C', C),
  ('D', D)  -- include additional columns here if you have more
) c (Field, value)
where rn <= 2 -- return top 2 dates
这是一本书。这将为您提供以下结果:

Field Today Yesterday ChangePercent 
----- ----- --------- ------------- 
A     1.1   1         10            
B     2.1   2         5             
C     3.1   3         3.33          
D     4.1   4         2.5           

字段的数量有限吗?是的。在现实世界的例子中,我有14个字段,您希望
max(date)
作为基础,并在此基础上计算
今天
昨天
?是的。这是正确的,字段的数量是有限的吗?是的。在现实世界的例子中,我有14个字段,您希望
max(date)
作为基础,并在此基础上计算
今天
昨天
?是的。没错,谢谢你。这很有效,你解释得很好。谢谢你。这很有效,你解释得很好。谢谢你的回答。我选择了下面一个更简洁的问题,但我感谢你的努力。谢谢你的回答。我选择了下面一个更简洁的查询,但我感谢您所做的努力。