我有两张表,如下所示
主表
ID keyword_tags
----------- ---------------------------------------------
10932 international foo data
和子表(id = fk_id的join子句)
fk_id date_value observ_value
----------- ----------------------- ----------------------
10932 2009-01-01 00:00:00.000 331.888888888
10932 2008-06-01 00:00:00.000 301.888888888
10932 2008-01-01 00:00:00.000 321.777777777
10932 2007-01-01 00:00:00.000 288.449066162
10932 2006-01-01 00:00:00.000 259.789733887
所需的输出是
ID keyword_tags Latest_Value Latest_Change Annual_Change
------ ---------------------- ------------- ------------- ---------------
10932 international foo data 331.888888888 30.000000000 10.111111111
,其中
Latest_Change = observ_value(of most recent date_value) - observ_value(of next most recent date_value)
Annual_Change = observ_value(of most recent date_value) - observ_value(of recent date_value - 1 year)
如何使用sql-server实现此目的?
答案 0 :(得分:1)
这应该有效:
我将表格创建为
create table master_table(
id int not null identity( 1, 1 )
, keyword_tags nvarchar( 127 ) not null
, constraint "master_PK" primary key clustered( "id" ) );
create table child_table(
id int not null identity( 1, 1 )
, fk_id int not null
, date_value datetime not null
, observ_value float not null
, constraint "child_PK" primary key clustered( "id" )
, constraint "child_FK_fkid" foreign key ( "fk_id" )
references master_table( "id" ) );
让我们插入一些数据:
insert into master_table select N'international foo data';
insert into master_table select N'national baz data';
insert into child_table--( "fk_id", "date_value", "observ_value" )
select 1, N'2009-01-01T00:00:00.000', 331.888888888
insert into child_table--( "fk_id", "date_value", "observ_value" )
select 1, N'2008-06-01T00:00:00.000', 301.888888888
insert into child_table--( "fk_id", "date_value", "observ_value" )
select 1, N'2008-01-01T00:00:00.000', 321.777777777
insert into child_table--( "fk_id", "date_value", "observ_value" )
select 1, N'2007-01-01T00:00:00.000', 288.449066162
insert into child_table--( "fk_id", "date_value", "observ_value" )
select 1, N'2006-01-01T00:00:00.000', 259.789733887;
insert into child_table--( "fk_id", "date_value", "observ_value" )
select 2, N'2003-07-01T00:00:00.000', 142.0
insert into child_table--( "fk_id", "date_value", "observ_value" )
select 2, N'2002-07-02T00:00:00.000', 123.0
insert into child_table--( "fk_id", "date_value", "observ_value" )
select 2, N'2002-07-01T00:00:00.000', 117.0
insert into child_table--( "fk_id", "date_value", "observ_value" )
select 2, N'2001-01-01T00:00:00.000', 107.0;
现在有趣的部分:
with currRow as (
select fk_id, MAX( date_value ) as currDate
from child_table
group by fk_id )
select currRow.fk_id, ct.ID, currRow.currDate, ct.observ_value
into #currRow
from currRow
inner join child_table as ct
on ct.date_value = currRow.currDate;
with lastEntry as (
select olderRows.fk_id, MAX( olderRows.date_value ) as date_value
from #currRow as currRow
inner join child_table as olderRows
on olderRows.fk_id = currRow.fk_id
and olderRows.date_value < currRow.currDate
group by olderRows.fk_id ),
oneYearAgo as (
select olderRows.fk_id, MAX( olderRows.date_value ) as date_value
from #currRow as currRow
inner join child_table as olderRows
on olderRows.fk_id = currRow.fk_id
and olderRows.date_value <= DATEADD( YEAR, -1, currRow.currDate )
group by olderRows.fk_id )
select
master_table.*
, currRow.ID as currID
, currRow.currDate
, currRow.observ_value as currObservValue
, lastData.id as lastPriorID
, lastData.date_value as lastPriorDateValue
, lastData.observ_value as lastPriorObservValue
, oneYearAgoData.id as oneYearAgoID
, oneYearAgoData.date_value as oneYearAgoDateValue
, oneYearAgoData.observ_value as oneYearAgoObservValue
from #currRow as currRow
inner join master_table
on master_table.id = currRow.fk_id
inner join lastEntry
on lastEntry.fk_id = currRow.fk_id
inner join child_table as lastData
on lastData.fk_id = lastEntry.fk_id
and lastData.date_value = lastEntry.date_value
inner join oneYearAgo
on oneYearAgo.fk_id = currRow.fk_id
inner join child_table as oneYearAgoData
on oneYearAgoData.fk_id = oneYearAgo.fk_id
and oneYearAgoData.date_value = oneYearAgo.date_value
从这些计算你的Latest_Change和Annual_Change留给读者练习。
答案 1 :(得分:0)
使用以下代码检索一个条目的值更改。您可以使用while循环或游标为主表中的多个条目重现此项,并使用以下查询执行检索的所有数据的并集。
select fk_id,[1] as current_value,[1] - [2] latest_change,[1]-[3] annual_change
from
(
select top 2 fk_id,observ_value ,ROW_NUMBER() over (order by date_value desc) row from child_table od
where fk_id in(10932)
union
select fk_id,observ_value,3 row from child_table
where fk_id=10932 and date_value =(select DATEADD(YY, -1, MAX(date_value))from child_table where fk_id=10932)
)as source_data pivot
(
max(observ_value) for row in ([1],[2],[3])
) pd