SQL:如何按某些列的值“拆分”表中的行?

Ket*_*ten 4 sql t-sql database sql-server select

我有一个表,其中的行如下:

姓名 日期_从 日期到 年龄
爱丽丝 2004年12月1日 2008年4月3日 35
鲍勃 2013年2月4日 2014年11月4日 43

我想制作一个表,将每一行按 date_fromdate_to列分成一年间隔,保留Name和 更新age,如下所示:

姓名 日期_从 日期到 年龄
爱丽丝 2004年12月1日 2005年12月1日 35
爱丽丝 2005年12月1日 2006年12月1日 36
爱丽丝 2006年12月1日 2007年12月1日 37
爱丽丝 2007年12月1日 2008年12月1日 38
爱丽丝 2008年12月1日 2008年4月3日 39
鲍勃 2013年2月4日 2014年2月4日 43
鲍勃 2014年2月4日 2014年11月4日 44

这可以用 SQL 实现吗?

GMB*_*GMB 5

一种解决方案是生成一个数字列表并将其与原始表连接起来,在开始日期上添加年份,直到到达结束日期。

以下查询最多处理 5 年跨度(要支持更多年数,您需要使用更多VALUESs 来扩展子查询)

SELECT
    name, 
    DATEADD(year, x.n, t.date_from) date_from,
    CASE 
        WHEN DATEADD(year, x.n + 1, t.date_from) > t.date_to 
        THEN date_to 
        ELSE DATEADD(year, x.n + 1, t.date_from) 
    END date_to,
    t.age + x.n age
FROM 
    mytable t
    INNER JOIN (
        VALUES(0), (1), (2), (3), (4), (5)
    ) x(n) ON DATEADD(year, x.n, t.date_from) <= t.date_to
ORDER BY name, age
Run Code Online (Sandbox Code Playgroud)

DB Fiddle 上的此演示使用您的示例数据返回:

name  | date_from           | date_to             | age
:---- | :------------------ | :------------------ | --:
Alice | 01/12/2004 00:00:00 | 01/12/2005 00:00:00 |  35
Alice | 01/12/2005 00:00:00 | 01/12/2006 00:00:00 |  36
Alice | 01/12/2006 00:00:00 | 01/12/2007 00:00:00 |  37
Alice | 01/12/2007 00:00:00 | 03/04/2008 00:00:00 |  38
Bob   | 04/02/2013 00:00:00 | 04/02/2014 00:00:00 |  43
Bob   | 04/02/2014 00:00:00 | 04/11/2014 00:00:00 |  44
Run Code Online (Sandbox Code Playgroud)