Sql 按年份和比例排列数据

Sql 按年份和比例排列数据,sql,sql-server,Sql,Sql Server,我有一个表格,格式如下: +---------+------------+------------+------------+----------+--+--+ | ENTITY | SUB_ENTITY | PROPORTION | START_DATE | END_DATE | | | +---------+------------+------------+------------+----------+--+--+ | 1000160 | 855960 | 0.6

我有一个表格,格式如下:

+---------+------------+------------+------------+----------+--+--+
| ENTITY  | SUB_ENTITY | PROPORTION | START_DATE | END_DATE |  |  |
+---------+------------+------------+------------+----------+--+--+
| 1000160 |     855960 | 0.6        |   19621001 | 20080702 |  |  |
| 1000203 |     054453 | 0.07       |   19720101 | 20170503 |  |  |
| 1000203 |     739846 | 0.07       |   19720101 | 20170503 |  |  |
| 1000203 |     283733 | 0.07       |   19720101 | 20170503 |  |  |
| 1000203 |     547953 | 3.33       |   19720101 | 20170503 |  |  |
| 1000203 |     984244 | 3.33       |   19720101 | NULL     |  |  |
| 1000233 |     857387 | 0.02       |   19541118 | NULL     |  |  |
| 1000233 |     862361 | 0.02       |   19541118 | NUILL    |  |  |
| 1000233 |     973876 | 0.02       |   19541118 | 20120321 |  |  |
| 1000233 |     017440 | NULL       |   19541118 | 20110714 |  |  |
| 1000233 |     575824 | NULL       |   19541118 | 20071127 |  |  |
| 1000241 |     006706 | 26         |   20030601 | 20130628 |  |  |
| 1000241 |     985828 | 27.2       |   20030601 | 20130628 |  |  |
| 1000241 |     060678 | 46.21      |   20030601 | 20180914 |  |  |
| 1000241 |     319255 | NULL       |   20030608 | 20130628 |  |  |
| 1000267 |     206424 | 5.73       |   19580901 | 20120530 |  |  |
| 1000267 |     599785 | 6.15       |   19580901 | 20120530 |  |  |
| 1000267 |     709129 | 6.7        |   19580901 | 20120530 |  |  |
| 1000267 |     805343 | 35.75      |   19580901 | 20120530 |  |  |
+---------+------------+------------+------------+----------+--+--+
注1:[结束日期=NULL]表示参与尚未结束。[比例=空]表示参与度为0

输出:我想知道每个子实体在每个活动年度的比例

注2:一个子实体可以是不同实体的一部分

最终的表格将类似于:

+---------+------------+------------------+------------+
| Entity  | Sub_Entity |       Year       | Proportion |
+---------+------------+------------------+------------+
| 1000160 |     855960 | 1962             | 0.6        |
| 1000160 |     855960 | .                | 0.6        |
| 1000160 |     855960 | .                | 0.6        |
| 1000160 |     855960 | 2008             | 0.6        |
| 1000203 |     054453 | 1972             | 0.07       |
| 1000203 |     054453 | .                | 0.07       |
| 1000203 |     054453 | .                | 0.07       |
| 1000203 |     054453 | 2017             | 0.07       |
| 1000203 |     739846 | 1972             | 0.07       |
| 1000203 |     739846 | .                | 0.07       |
| 1000203 |     739846 | .                | 0.07       |
| 1000203 |     739846 | 2017             | 0.07       |
| 1000203 |     547953 | 1972             | 3.33       |
| 1000203 |     547953 | .                | 3.33       |
| 1000203 |     547953 | .                | 3.33       |
| 1000203 |     547953 | 2017             | 3.33       |
| 1000203 |     984244 | 1972             | 3.33       |
| 1000203 |     984244 | .                | 3.33       |
| 1000203 |     984244 | .                | 3.33       |
| 1000203 |     984244 | (This Year 2019) | 3.33       |
|         |            |                  |            |
+---------+------------+------------------+------------+

注3:我用点来表示这一范围内的年份。

试试这个回归主义者:

select 1000160 as ENTITY,    855960 as SUB_ENTITY, 0.6    as PROPORTION,  
19621001 as START_DATE, 20080702 as END_DATE 
into #tmp
union select 1000203, 054453, 0.07      ,   19720101, 20170503
union select 1000203, 739846, 0.07      ,   19720101, 20170503 
union select 1000203, 283733, 0.07      ,   19720101, 20170503 
union select 1000203, 547953, 3.33      ,   19720101, 20170503 
union select 1000203, 984244, 3.33      ,   19720101, NULL     
union select 1000233, 857387, 0.02      ,   19541118, NULL     
union select 1000233, 862361, 0.02      ,   19541118, NULL    
union select 1000233, 973876, 0.02      ,   19541118, 20120321 
union select 1000233, 017440, NULL      ,   19541118, 20110714 
union select 1000233, 575824, NULL      ,   19541118, 20071127 
union select 1000241, 006706, 26        ,   20030601, 20130628 
union select 1000241, 985828, 27.2      ,   20030601, 20130628 
union select 1000241, 060678, 46.21     ,   20030601, 20180914 
union select 1000241, 319255, NULL      ,   20030608, 20130628 
union select 1000267, 206424, 5.73      ,   19580901, 20120530 
union select 1000267, 599785, 6.15      ,   19580901, 20120530 
union select 1000267, 709129, 6.7       ,   19580901, 20120530 
union select 1000267, 805343, 35.75     ,   19580901, 20120530

select ENTITY, SUB_ENTITY , left(START_DATE,4) + n,  PROPORTION  from #tmp cross join 
(
    SELECT TOP (100) n = CONVERT(INT, ROW_NUMBER() OVER (ORDER BY s1.[object_id]))-1
    FROM sys.all_objects AS s1 CROSS JOIN sys.all_objects AS s2 
)a
where left(START_DATE,4)  + n <= left(isnull(END_DATE, year(getdate())),4) --and ENTITY =  1000203 and SUB_ENTITY = 984244     
order by 2
给我一个介于0和99之间的数字。 通过交叉连接,只要开始日期+0..99不超过结束日期或当前年份为结束日期为空,我就在开始日期中每年添加这些数字


希望它更清晰一点

如果我理解正确,您可以使用递归CTE:

with cte as (
      select Entity, Sub_Entity, year(start_date) as year, Proportion, year(end_date) as end_year
      from t
      union all
      select Entity, Sub_Entity, year + 1, Proportion, end_year
      from cte
      where end_year < year
     )
select Entity, Sub_Entity, year, proportion
from cte;

如果年数可以超过100,则需要添加选项MAXRECURSION 0。

请向我们展示您的尝试。为什么在cte结构中使用cte@戈登Linoff@Regressionist . . . 这恰好是递归CTE的默认名称。否则,我有一种倾向,就是在第二个FROM子句中的名称不对齐。这似乎很有效。你能解释一下你在这里使用的一些逻辑吗@拉链
with cte as (
      select Entity, Sub_Entity, year(start_date) as year, Proportion, year(end_date) as end_year
      from t
      union all
      select Entity, Sub_Entity, year + 1, Proportion, end_year
      from cte
      where end_year < year
     )
select Entity, Sub_Entity, year, proportion
from cte;