返回行的视图重复了由金额字段值表示的次数

时间:2012-04-13 18:08:38

标签: sql-server-2008 tsql

我有一个包含美元金额字段的会计表。我想创建一个视图,该视图将返回每一分钱的一行,其中包含表中的一些其他字段。

所以作为一个非常简单的例子,假设我有这样一行:

PK     Amount     Date
---------------------------
123    4.80       1/1/2012

查询/视图应返回480行(每个便士一行),如下所示:

PK      Date
-----------------
123     1/1/2012

实现这一目标的最佳方式是什么?我有一个使用表值函数和临时表的解决方案,但在我的脑海中,我一直认为必须有一种方法来实现传统视图。可能是一个创造性的交叉连接或者会返回这个结果的东西,而不必以临时表和tbf等形式声明太多资源。任何想法?

2 个答案:

答案 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);

Here is the SqlFiddle

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年。