将单行数据插入多行table
Insert a single line of data into multiple rows of table
概要:如何编写 SQL 代码以将平面文件中的一条记录插入要插入 SQL 服务器 table 的单独记录中 table。
细节:我有一个 table 来记录租赁付款。对于每份租赁协议,到期日始终是每月的第一天。 table 中每个月在租约期间都有一个条目。为简单起见,假设有一份从 2019 年 9 月 1 日到 2020 年 8 月 31 日的租赁合同。table 看起来像这样:
+------------------------------------------------------+
| CONTRACT_ID | DUE_DATE_DT | INVOICE_ID | RENTAL_AMT |
+-------------+-------------+------------+-------------+
| 12345 | 9/1/2019 | | |
+-------------+-------------+------------+-------------+
| 12345 | 10/1/2019 | | |
+-------------+-------------+------------+-------------+
...
+-------------+-------------+------------+-------------+
| 12345 | 8/1/2020 | | |
+-------------+-------------+------------+-------------+
发票通常为一个日历月,但有时可能有两三个月,因为供应商正在追赶。数据以平面文件形式接收,样本如下所示:
Contract Rental Period From Date Rental Period To Date Invoice Number Amount
31125 9/1/2019 9/30/2019 6378 400.00 (standard scenario)
12345 9/1/2019 11/30/2019 789 150.00 (multi-month scenario)
平面文件中的数据需要存储在 table 中的三个单独的记录中:
+------------------------------------------------------+
| CONTRACT_ID | DUE_DATE_DT | INVOICE_ID | RENTAL_AMT |
+-------------+-------------+------------+-------------+
| 12345 | 9/1/2019 | 789 | 50.00 |
+-------------+-------------+------------+-------------+
| 12345 | 10/1/2019 | 789 | 50.00 |
+-------------+-------------+------------+-------------+
| 12345 | 11/1/2019 | 789 | 50.00 |
+-------------+-------------+------------+-------------+
提前致谢。
您可以尝试使用递归CTE。考虑一下:
CREATE TABLE #RawData(Contract int, Rental_Period_From Date, Rental_Period_To Date, Invoice_Number int, Amount Decimal(10,2))
INSERT INTO #RawData VALUES(31225, '9/1/2019','9/30/2019', 6378,400.00)
INSERT INTO #RawData VALUES(12345, '9/1/2019','11/30/2019', 789,150.00)
;WITH CTE
AS
(
select Contract,Rental_Period_From DueDate,Invoice_Number,Amount, 0 MonthCounter, Rental_Period_To from #RawData
UNION ALL
SELECT Contract, DATEADD(month,MonthCounter+1,DueDate),Invoice_Number,Amount, MonthCounter,Rental_Period_To from CTE
WHERE DATEADD(month,MonthCounter+1,DueDate) <= Rental_Period_To
)
SELECT CONTRACT, DueDate,Invoice_Number, CAST(Amount / (SELECT COUNT(*)
FROM CTE t1 WHERE t1.Contract = t2.Contract ) as decimal(10,2)) Amount
FROM CTE t2
概要:如何编写 SQL 代码以将平面文件中的一条记录插入要插入 SQL 服务器 table 的单独记录中 table。
细节:我有一个 table 来记录租赁付款。对于每份租赁协议,到期日始终是每月的第一天。 table 中每个月在租约期间都有一个条目。为简单起见,假设有一份从 2019 年 9 月 1 日到 2020 年 8 月 31 日的租赁合同。table 看起来像这样:
+------------------------------------------------------+
| CONTRACT_ID | DUE_DATE_DT | INVOICE_ID | RENTAL_AMT |
+-------------+-------------+------------+-------------+
| 12345 | 9/1/2019 | | |
+-------------+-------------+------------+-------------+
| 12345 | 10/1/2019 | | |
+-------------+-------------+------------+-------------+
...
+-------------+-------------+------------+-------------+
| 12345 | 8/1/2020 | | |
+-------------+-------------+------------+-------------+
发票通常为一个日历月,但有时可能有两三个月,因为供应商正在追赶。数据以平面文件形式接收,样本如下所示:
Contract Rental Period From Date Rental Period To Date Invoice Number Amount
31125 9/1/2019 9/30/2019 6378 400.00 (standard scenario)
12345 9/1/2019 11/30/2019 789 150.00 (multi-month scenario)
平面文件中的数据需要存储在 table 中的三个单独的记录中:
+------------------------------------------------------+
| CONTRACT_ID | DUE_DATE_DT | INVOICE_ID | RENTAL_AMT |
+-------------+-------------+------------+-------------+
| 12345 | 9/1/2019 | 789 | 50.00 |
+-------------+-------------+------------+-------------+
| 12345 | 10/1/2019 | 789 | 50.00 |
+-------------+-------------+------------+-------------+
| 12345 | 11/1/2019 | 789 | 50.00 |
+-------------+-------------+------------+-------------+
提前致谢。
您可以尝试使用递归CTE。考虑一下:
CREATE TABLE #RawData(Contract int, Rental_Period_From Date, Rental_Period_To Date, Invoice_Number int, Amount Decimal(10,2))
INSERT INTO #RawData VALUES(31225, '9/1/2019','9/30/2019', 6378,400.00)
INSERT INTO #RawData VALUES(12345, '9/1/2019','11/30/2019', 789,150.00)
;WITH CTE
AS
(
select Contract,Rental_Period_From DueDate,Invoice_Number,Amount, 0 MonthCounter, Rental_Period_To from #RawData
UNION ALL
SELECT Contract, DATEADD(month,MonthCounter+1,DueDate),Invoice_Number,Amount, MonthCounter,Rental_Period_To from CTE
WHERE DATEADD(month,MonthCounter+1,DueDate) <= Rental_Period_To
)
SELECT CONTRACT, DueDate,Invoice_Number, CAST(Amount / (SELECT COUNT(*)
FROM CTE t1 WHERE t1.Contract = t2.Contract ) as decimal(10,2)) Amount
FROM CTE t2