在多行中拆分行
Split Rows in multiple rows
我需要把一行分成几行
例如,我有这个结果,它表示用户应该分几期付款的总金额,每期付款都有某个日期,基于分期付款间隔,所以每个 TotalSum 除以 InstallsmentNoTotal,即每个 Installment金额,对于第一期的 InstallmentDate 是 FirstInstallmentDate,但对于每一期,我们应该添加 InstallsmentInterval 天数。
DECLARE @temTable TABLE
(
Id INT,
TotalSum DECIMAL(18, 0),
InstallsmentNoTotal INT,
InstallsmentInterval INT,
FirstInstallmentDate DATE
);
INSERT INTO @temTable
(
Id,
TotalSum,
InstallsmentNoTotal,
InstallsmentInterval,
FirstInstallmentDate
)
VALUES
(1, 6000, 3, 30, '2020-08-01'),
(2, 8000, 2, 60, '2020-10-01'),
(3, 5000, 1, 0, '2020-08-01')
SELECT * FROM @temTable
Id TotalSum InstallsmentNoTotal InstallsmentInterval FirstInstallmentDate
1 6000 3 30 2020-08-01
2 8000 2 60 2020-10-01
3 5000 1 0 2020-08-01
我需要像这样显示每一行的数据:
SaleId InstallmentNo InstallmensAmount NextInstallmentDate
1 1 2000 2020-08-01
1 2 2000 2020-09-01
1 3 2000 2020-10-01
2 1 4000 2020-10-01
2 2 4000 2020-12-01
3 1 5000 2020-08-01
我尝试使用 Cursors、Cross Apply,但我无法管理工作。
提前感谢您的帮助
您可以使用递归查询:
with cte as (
select
id saleId,
1 InstallmentNo,
TotalSum / InstallsmentNoTotal InstallmentAmount,
FirstInstallmentDate NextInstallmentDate,
InstallsmentInterval,
InstallsmentNoTotal
from @temTable
union all
select
saleId,
InstallmentNo + 1,
InstallmentAmount,
cast(dateadd(day, InstallsmentInterval, NextInstallmentDate) as date),
InstallsmentInterval,
InstallsmentNoTotal
from cte
where InstallmentNo < InstallsmentNoTotal
)
select saleId, InstallmentAmount, InstallmentAmount, NextInstallmentDate
from cte
order by saleId, InstallmentNo
对于您的示例数据,this returns:
saleId | InstallmentAmount | InstallmentAmount | NextInstallmentDate
-----: | ----------------: | ----------------: | :------------------
1 | 2000.00000000000 | 2000.00000000000 | 2020-08-01
1 | 2000.00000000000 | 2000.00000000000 | 2020-08-31
1 | 2000.00000000000 | 2000.00000000000 | 2020-09-30
2 | 4000.00000000000 | 4000.00000000000 | 2020-10-01
2 | 4000.00000000000 | 4000.00000000000 | 2020-11-30
3 | 5000.00000000000 | 5000.00000000000 | 2020-08-01
你可以看到日期算法不是你想要的。如果您打算按月增加日期,那么您应该存储月数而不是天数(并在 CTE 的递归成员中将 dateadd(day, ...)
修改为 dateadd(month, ...)
。
这是符合要求的基于“计数”table 的方法。这种方法是一种简单有效的基于数字或计数 table 计算前向的方法。在这种情况下,我将其设置为 6 个值,但它可以增加到任何需要的值(以满足最大 InstallsmentNoTotal)。基于 Imo 计数的方法更简单、更易读,并且(在极限内)更快。
数据
create table #temTable
(
Id INT,
TotalSum DECIMAL(18, 0),
InstallsmentNoTotal INT,
InstallsmentInterval INT,
FirstInstallmentDate DATE
);
INSERT INTO #temTable
(
Id,
TotalSum,
InstallsmentNoTotal,
InstallsmentInterval,
FirstInstallmentDate
)
VALUES
(1, 6000, 3, 30, '2020-08-01'),
(2, 8000, 2, 60, '2020-10-01'),
(3, 5000, 1, 0, '2020-08-01');
查询
select id SaleId, t.TotalSum/t.InstallsmentNoTotal InstallmentAmount,
dateadd(month, (InstallsmentInterval/30)*(tally.n-1), FirstInstallmentDate) NextInstallmentDate
from #temTable t
cross apply
(select n from (values (1),(2),(3),(4),(5),(6)) v(n)
where n<=t.InstallsmentNoTotal) tally;
输出
SaleId InstallmentAmount NextInstallmentDate
1 2000.00000000000 2020-08-01
1 2000.00000000000 2020-09-01
1 2000.00000000000 2020-10-01
2 4000.00000000000 2020-10-01
2 4000.00000000000 2020-12-01
3 5000.00000000000 2020-08-01
你可以通过CTE来获得结果集。
;WITH CTE_Installments as
(
SELECT Id,TotalSum/InstallsmentNoTotal AS InstallmentSum
,1 as CurrentinstallmentNo, InstallsmentNoTotal,
dateadd(dd,InstallsmentInterval,FirstInstallmentDate) as nextInstallmentDate, InstallsmentInterval FROM @temTable
union all
SELECT Id, InstallmentSum, CurrentInstallmentNo+1 as currentinstallmentNo, InstallsmentNoTotal,
dateadd(dd,InstallsmentInterval,nextInstallmentDate) as nextInstallmentDate, InstallsmentInterval
from CTE_Installments
where CurrentinstallmentNo < InstallsmentNoTotal
)
SELECT Id as salesId, CurrentinstallmentNo as InstallmentNo, InstallmentSum,nextInstallmentDate
FROM CTE_Installments
order by Id
+---------+---------------+------------------+---------------------+
| salesId | InstallmentNo | InstallmentSum | nextInstallmentDate |
+---------+---------------+------------------+---------------------+
| 1 | 1 | 2000.00000000000 | 2020-08-31 |
| 1 | 2 | 2000.00000000000 | 2020-09-30 |
| 1 | 3 | 2000.00000000000 | 2020-10-30 |
| 2 | 1 | 4000.00000000000 | 2020-11-30 |
| 2 | 2 | 4000.00000000000 | 2021-01-29 |
| 3 | 1 | 5000.00000000000 | 2020-08-01 |
+---------+---------------+------------------+---------------------+
我需要把一行分成几行
例如,我有这个结果,它表示用户应该分几期付款的总金额,每期付款都有某个日期,基于分期付款间隔,所以每个 TotalSum 除以 InstallsmentNoTotal,即每个 Installment金额,对于第一期的 InstallmentDate 是 FirstInstallmentDate,但对于每一期,我们应该添加 InstallsmentInterval 天数。
DECLARE @temTable TABLE
(
Id INT,
TotalSum DECIMAL(18, 0),
InstallsmentNoTotal INT,
InstallsmentInterval INT,
FirstInstallmentDate DATE
);
INSERT INTO @temTable
(
Id,
TotalSum,
InstallsmentNoTotal,
InstallsmentInterval,
FirstInstallmentDate
)
VALUES
(1, 6000, 3, 30, '2020-08-01'),
(2, 8000, 2, 60, '2020-10-01'),
(3, 5000, 1, 0, '2020-08-01')
SELECT * FROM @temTable
Id TotalSum InstallsmentNoTotal InstallsmentInterval FirstInstallmentDate
1 6000 3 30 2020-08-01
2 8000 2 60 2020-10-01
3 5000 1 0 2020-08-01
我需要像这样显示每一行的数据:
SaleId InstallmentNo InstallmensAmount NextInstallmentDate
1 1 2000 2020-08-01
1 2 2000 2020-09-01
1 3 2000 2020-10-01
2 1 4000 2020-10-01
2 2 4000 2020-12-01
3 1 5000 2020-08-01
我尝试使用 Cursors、Cross Apply,但我无法管理工作。
提前感谢您的帮助
您可以使用递归查询:
with cte as (
select
id saleId,
1 InstallmentNo,
TotalSum / InstallsmentNoTotal InstallmentAmount,
FirstInstallmentDate NextInstallmentDate,
InstallsmentInterval,
InstallsmentNoTotal
from @temTable
union all
select
saleId,
InstallmentNo + 1,
InstallmentAmount,
cast(dateadd(day, InstallsmentInterval, NextInstallmentDate) as date),
InstallsmentInterval,
InstallsmentNoTotal
from cte
where InstallmentNo < InstallsmentNoTotal
)
select saleId, InstallmentAmount, InstallmentAmount, NextInstallmentDate
from cte
order by saleId, InstallmentNo
对于您的示例数据,this returns:
saleId | InstallmentAmount | InstallmentAmount | NextInstallmentDate -----: | ----------------: | ----------------: | :------------------ 1 | 2000.00000000000 | 2000.00000000000 | 2020-08-01 1 | 2000.00000000000 | 2000.00000000000 | 2020-08-31 1 | 2000.00000000000 | 2000.00000000000 | 2020-09-30 2 | 4000.00000000000 | 4000.00000000000 | 2020-10-01 2 | 4000.00000000000 | 4000.00000000000 | 2020-11-30 3 | 5000.00000000000 | 5000.00000000000 | 2020-08-01
你可以看到日期算法不是你想要的。如果您打算按月增加日期,那么您应该存储月数而不是天数(并在 CTE 的递归成员中将 dateadd(day, ...)
修改为 dateadd(month, ...)
。
这是符合要求的基于“计数”table 的方法。这种方法是一种简单有效的基于数字或计数 table 计算前向的方法。在这种情况下,我将其设置为 6 个值,但它可以增加到任何需要的值(以满足最大 InstallsmentNoTotal)。基于 Imo 计数的方法更简单、更易读,并且(在极限内)更快。
数据
create table #temTable
(
Id INT,
TotalSum DECIMAL(18, 0),
InstallsmentNoTotal INT,
InstallsmentInterval INT,
FirstInstallmentDate DATE
);
INSERT INTO #temTable
(
Id,
TotalSum,
InstallsmentNoTotal,
InstallsmentInterval,
FirstInstallmentDate
)
VALUES
(1, 6000, 3, 30, '2020-08-01'),
(2, 8000, 2, 60, '2020-10-01'),
(3, 5000, 1, 0, '2020-08-01');
查询
select id SaleId, t.TotalSum/t.InstallsmentNoTotal InstallmentAmount,
dateadd(month, (InstallsmentInterval/30)*(tally.n-1), FirstInstallmentDate) NextInstallmentDate
from #temTable t
cross apply
(select n from (values (1),(2),(3),(4),(5),(6)) v(n)
where n<=t.InstallsmentNoTotal) tally;
输出
SaleId InstallmentAmount NextInstallmentDate
1 2000.00000000000 2020-08-01
1 2000.00000000000 2020-09-01
1 2000.00000000000 2020-10-01
2 4000.00000000000 2020-10-01
2 4000.00000000000 2020-12-01
3 5000.00000000000 2020-08-01
你可以通过CTE来获得结果集。
;WITH CTE_Installments as
(
SELECT Id,TotalSum/InstallsmentNoTotal AS InstallmentSum
,1 as CurrentinstallmentNo, InstallsmentNoTotal,
dateadd(dd,InstallsmentInterval,FirstInstallmentDate) as nextInstallmentDate, InstallsmentInterval FROM @temTable
union all
SELECT Id, InstallmentSum, CurrentInstallmentNo+1 as currentinstallmentNo, InstallsmentNoTotal,
dateadd(dd,InstallsmentInterval,nextInstallmentDate) as nextInstallmentDate, InstallsmentInterval
from CTE_Installments
where CurrentinstallmentNo < InstallsmentNoTotal
)
SELECT Id as salesId, CurrentinstallmentNo as InstallmentNo, InstallmentSum,nextInstallmentDate
FROM CTE_Installments
order by Id
+---------+---------------+------------------+---------------------+
| salesId | InstallmentNo | InstallmentSum | nextInstallmentDate |
+---------+---------------+------------------+---------------------+
| 1 | 1 | 2000.00000000000 | 2020-08-31 |
| 1 | 2 | 2000.00000000000 | 2020-09-30 |
| 1 | 3 | 2000.00000000000 | 2020-10-30 |
| 2 | 1 | 4000.00000000000 | 2020-11-30 |
| 2 | 2 | 4000.00000000000 | 2021-01-29 |
| 3 | 1 | 5000.00000000000 | 2020-08-01 |
+---------+---------------+------------------+---------------------+