T-SQL从一个记录创建多个记录

时间:2018-02-16 05:32:13

标签: sql-server tsql

我有成本记录,我想从中创建N条记录。 子记录有一些不同的参数。 例如:

父母记录:

date     |  amount | duration
20170201 | 5000    | 5 months

孩子们记录:

date     |  amount | duration
20170301 |  1000   | 1 months 
20170401 |  1000   | 1 months 
20170501 |  1000   | 1 months
20170601 |  1000   | 1 months
20170701 |  1000   | 1 months

如何在没有迭代的情况下完成此操作?没有光标或同时?

3 个答案:

答案 0 :(得分:1)

假设你有一个如下表:

create table tblRecords ( date int, amount money, duration int);
insert into tblRecords values
(20170201,5000,5),
(20180101,9000,3);

您可以使用如下查询:

select  
    date= date + r*100
    ,amount= amount/duration
    ,duration =1 
from tblRecords
cross apply
(
    select top  (select duration)
    r= row_number() over(order by (select null))
    from 
    sys.objects s1 
    cross join 
    sys.objects s2
) h

see working demo

答案 1 :(得分:1)

以下SQL CTE查询可以基于Abdul的解决方案

使用
/*
Create Table PARENT (PARENT_DATE DATE, PARENT_AMOUNT DECIMAL(18,2),PARENT_MONTH INT)
INSERT INTO PARENT SELECT '20170201',5000 ,5
INSERT INTO PARENT SELECT '20180601',120 ,3
*/
;WITH CTE_CHILD
AS  (

    SELECT
        Parent_Date,
        Parent_Amount,
        Parent_Month,
        DateAdd(Month, 1, Parent_Date) as Child_Date,
        Parent_Amount/Parent_Month  AS Child_Amount,
        1 AS Child_Duration
    FROM Parent

    UNION ALL

    SELECT
        Parent_Date,
        Parent_Amount,
        Parent_Month,
        DateAdd(Month, 1, Child_Date) as Child_Date,
        Child_Amount,
        Child_Duration
    FROM CTE_CHILD
    WHERE 
        DateAdd(Month, 1, Child_Date) <= DateAdd(Month, Parent_Month, Parent_Date)

)
SELECT
    Child_Date,
    Child_Amount,
    Child_Duration
 FROM CTE_CHILD

答案 2 :(得分:0)

一种方法是CTE

DECLARE @PARENT AS TABLE
    (PARENT_DATE DATE, PARENT_AMOUNT DECIMAL(18,2),PARENT_MONTH INT)
INSERT INTO @PARENT
SELECT '20170201',5000 ,5

;WITH CTE_CHILD
AS  (
    SELECT  DATEADD(MONTH,1,PARENT_DATE) AS CHILD_DATE
            ,PARENT_AMOUNT/PARENT_MONTH  AS CHILD_AMOUNT
            ,1                           AS CHILD_DURATION
    FROM    @PARENT
    WHERE   DATEADD(MONTH,1,PARENT_DATE) <= DATEADD(MONTH,PARENT_MONTH,PARENT_DATE)
    UNION ALL
    SELECT  DATEADD(MONTH,1,CHILD_DATE)
            ,PARENT_AMOUNT/PARENT_MONTH
            ,1
    FROM    CTE_CHILD
    INNER JOIN @PARENT ON DATEADD(MONTH,1,CHILD_DATE) <= DATEADD(MONTH,PARENT_MONTH,PARENT_DATE)
)
SELECT * FROM CTE_CHILD 
option (maxrecursion 0)

输出: -

CHILD_DATE  CHILD_AMOUNT        CHILD_DURATION
2017-03-01  1000.0000000000000  1
2017-04-01  1000.0000000000000  1
2017-05-01  1000.0000000000000  1
2017-06-01  1000.0000000000000  1
2017-07-01  1000.0000000000000  1