Sql 使用Pivot计算最近两天的数据更改百分比
我有一个表,其中包含每天收集的一组数据(我使用SQL Server 2016) 我正在尝试编写一个查询,该查询将显示最近两天和%的更改,并返回如下结果: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%
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)
作为基础,并在此基础上计算今天
和昨天
?是的。没错,谢谢你。这很有效,你解释得很好。谢谢你。这很有效,你解释得很好。谢谢你的回答。我选择了下面一个更简洁的问题,但我感谢你的努力。谢谢你的回答。我选择了下面一个更简洁的查询,但我感谢您所做的努力。