我有一个包含美元金额字段的会计表。我想创建一个视图,该视图将返回每一分钱的一行,其中包含表中的一些其他字段。
所以作为一个非常简单的例子,假设我有这样一行:
PK Amount Date
---------------------------
123 4.80 1/1/2012
查询/视图应返回480行(每个便士一行),如下所示:
PK Date
-----------------
123 1/1/2012
实现这一目标的最佳方式是什么?我有一个使用表值函数和临时表的解决方案,但在我的脑海中,我一直认为必须有一种方法来实现传统视图。可能是一个创造性的交叉连接或者会返回这个结果的东西,而不必以临时表和tbf等形式声明太多资源。任何想法?
答案 0 :(得分:3)
您可以使用CTE,如下所示:
WITH duplicationCTE AS
(
SELECT PK, Date, Amount, 1 AS Count
FROM myTable
UNION ALL
SELECT myTable.PK, myTable.Date, myTable.Amount, Count+1
FROM myTable
JOIN duplicationCTE ON myTable.PK = duplicationCTE.PK
WHERE Count+1 <= myTable.Amount*100
)
SELECT PK, Date
FROM duplicationCTE
OPTION (MAXRECURSION 0);
AND,请注意0.这意味着它可以无限运行(危险顺便说一句)否则,32676是您可以设置的最大递归数(默认值为100)。但是,如果您运行的是32676循环,那么您可能需要重新考虑您的逻辑:)
答案 1 :(得分:3)
在numbers table的帮助下,您可以这样做:
select PK, [Date]
from YourTable as T
inner join number as N
on N.n between 1 and T.Amount * 100
如果你周围没有,你想测试它,你可以使用master..spt_values。
declare @T table
(
PK int,
Amount money,
[Date] date
)
insert into @T values
(123, 4.80, '20120101')
;with number(n) as
(
select number
from master..spt_values
where type = 'P'
)
select PK, [Date]
from @T as T
inner join number as N
on N.n between 1 and T.Amount * 100
<强>更新强>
来自Jeff Moden的文章
The "Numbers" or "Tally" Table: What it is and how it replaces a loop.
Tally表只不过是一个包含单列的表 非常好的索引序列号从0或1开始(我的开始于 1)并上升到一些数字。 Tally表中最大的数字 不应该只是一些武断的选择。它应该基于什么 你认为你会用它。我把VARCHAR(8000)与我分开了,所以它 必须至少8000个数字。因为我偶尔需要生成 30年的约会,我保留了我的大部分生产Tally表11,000 或更多,超过365.25天,30年。