我需要一个包含每个月记录的表,而不是包含重复计数字段的表。
我的数据目前看起来像这样:
Property Item Month Repeat_Count Amount
------------------------------------------------------------------
A Rent 1/1/2016 1 100
A Rent 2/1/2016 1 105
A Rent 3/1/2016 3 110
A Rent 6/1/2016 1 115
A Rent 7/1/2016 6 120
A Rent 1/1/2017 1 125
我希望它看起来像这样:
Property Item Month Amount
-----------------------------------------
A Rent 1/1/2016 100
A Rent 2/1/2016 105
A Rent 3/1/2016 110
A Rent 4/1/2016 110
A Rent 5/1/2016 110
A Rent 6/1/2016 115
A Rent 7/1/2016 120
A Rent 8/1/2016 120
A Rent 9/1/2016 120
A Rent 10/1/2016 120
A Rent 11/1/2016 120
A Rent 12/1/2016 120
A Rent 1/1/2017 125
希望我能很好地解释这个,谢谢!
答案 0 :(得分:2)
我使用table of numbers和CROSS APPLY
。
数字表只是一个表,其中一列的整数从1到足够大,例如100,000。我个人使用100K数字的表。 Aaron Bertrand写了一篇good article来解释如何生成这样的表格。
示例数据
DECLARE @T TABLE ([Property] varchar(50), [Item] varchar(50), [Month] datetime, [Repeat_Count] int, [Amount] int);
INSERT INTO @T ([Property], [Item], [Month], [Repeat_Count], [Amount]) VALUES
('A', 'Rent', '2016-01-01 00:00:00', 1, 100),
('A', 'Rent', '2016-02-01 00:00:00', 1, 105),
('A', 'Rent', '2016-03-01 00:00:00', 3, 110),
('A', 'Rent', '2016-06-01 00:00:00', 1, 115),
('A', 'Rent', '2016-07-01 00:00:00', 6, 120),
('A', 'Rent', '2017-01-01 00:00:00', 1, 125);
<强>查询强>
SELECT *
FROM
@T AS T
CROSS APPLY
(
SELECT
DATEADD(day, dbo.Numbers.Number-1, T.Month) AS NewDate
FROM dbo.Numbers
WHERE dbo.Numbers.Number <= T.Repeat_Count
) AS CA
ORDER BY NewDate;
<强>结果强>
+----------+------+-------------------------+--------------+--------+-------------------------+
| Property | Item | Month | Repeat_Count | Amount | NewDate |
+----------+------+-------------------------+--------------+--------+-------------------------+
| A | Rent | 2016-01-01 00:00:00.000 | 1 | 100 | 2016-01-01 00:00:00.000 |
| A | Rent | 2016-02-01 00:00:00.000 | 1 | 105 | 2016-02-01 00:00:00.000 |
| A | Rent | 2016-03-01 00:00:00.000 | 3 | 110 | 2016-03-01 00:00:00.000 |
| A | Rent | 2016-03-01 00:00:00.000 | 3 | 110 | 2016-03-02 00:00:00.000 |
| A | Rent | 2016-03-01 00:00:00.000 | 3 | 110 | 2016-03-03 00:00:00.000 |
| A | Rent | 2016-06-01 00:00:00.000 | 1 | 115 | 2016-06-01 00:00:00.000 |
| A | Rent | 2016-07-01 00:00:00.000 | 6 | 120 | 2016-07-01 00:00:00.000 |
| A | Rent | 2016-07-01 00:00:00.000 | 6 | 120 | 2016-07-02 00:00:00.000 |
| A | Rent | 2016-07-01 00:00:00.000 | 6 | 120 | 2016-07-03 00:00:00.000 |
| A | Rent | 2016-07-01 00:00:00.000 | 6 | 120 | 2016-07-04 00:00:00.000 |
| A | Rent | 2016-07-01 00:00:00.000 | 6 | 120 | 2016-07-05 00:00:00.000 |
| A | Rent | 2016-07-01 00:00:00.000 | 6 | 120 | 2016-07-06 00:00:00.000 |
| A | Rent | 2017-01-01 00:00:00.000 | 1 | 125 | 2017-01-01 00:00:00.000 |
+----------+------+-------------------------+--------------+--------+-------------------------+
答案 1 :(得分:1)
您可以使用Tally Table生成日期:
WITH E1(N) AS( -- 10 ^ 1 = 10 rows
SELECT 1 FROM(VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))t(N)
),
E2(N) AS(SELECT 1 FROM E1 a CROSS JOIN E1 b), -- 10 ^ 2 = 100 rows
E4(N) AS(SELECT 1 FROM E2 a CROSS JOIN E2 b), -- 10 ^ 4 = 10,000 rows
CteTally(N) AS(
SELECT TOP(SELECT MAX(Repeat_Count) FROM tbl) ROW_NUMBER() OVER(ORDER BY(SELECT NULL))
FROM E4
)
SELECT
t.Property,
t.Item,
[Month] = DATEADD(MONTH, c.N-1, t.Month),
t.Amount
FROM tbl t
INNER JOIN CteTally c
ON c.N <= t.Repeat_Count
ORDER BY t.Property, t.Item, [Month]