繁体   English   中英

SQL 当列值按日期大于 1 时基于拆分行

[英]SQL split row based when column value is greater than 1 by date

我有一个表,我需要根据一个日期列和另一个值列来拆分列。

本质上,当数字列大于一时,我需要在同一日期将该列拆分,直到该列等于一。

例如,这是进来的数据集

+----------------------------------------------+
|     CONF#   DATE       Numbers     Rev       |
+----------------------------------------------+
| ------- ----------- ----------- -----------  |
| 24720   01/10/2014  1           35           |
| 24437   11/09/2014  2           450          |
| 24007   04/08/2014  3           15           |
| 24628   25/09/2014  1           100          |
+----------------------------------------------+

我正在寻找的结果

+----------------------------------------------+
|     CONF#   DATE        Numbers     Rev      |
+----------------------------------------------+
| ------- ----------- ----------- -----------  |
| 24720   01/10/2014  1           35           |
| 24437   11/09/2014  1           225          |
| 24437   11/10/2014  1           225          |
| 24007   04/08/2014  1           5            |
| 24007   04/09/2014  1           5            |
| 24007   04/10/2014  1           5            |
| 24628   25/09/2014  1           100          |
+----------------------------------------------+

结果集返回时将大于一的行分解。 rev 在分解的行中平均分配。

我正在尝试为此编写 cursor

    DECLARE cursor_SplitRow CURSOR
FOR SELECT 
      [Conf#]
FROM [table];

OPEN cursor_SplitRow;
FETCH NEXT FROM cursor_SplitRow INTO 
@Conf#;
WHILE @@FETCH_STATUS = 0
BEGIN
    DECLARE @counter INT = 1;
    WHILE @counter <= @Numbers
        BEGIN
            INSERT INTO #TemptTable
            VALUES(@CONF#  ,
                   @DATE,
                   1,
                   @Rev/@numbers

我认为代码需要运行以除以它超过一的数量,所以如果数字是 5,则收入必须除以 5 并平均分配,这就是我卡住的地方

不要使用 cursor。 使用递归 CTE:

with cte as (
      select conf#, date, numbers, rev / numbers as rev, 1 as n
      from t
      union all
      select conf#, dateadd(day, 1, date), numbers, rev, n + 1
      from cte
      where n < numbers
     )
select conf#, date, 1 as n, rev
from cte;

如果你手边有一个数字或计数表,你也可以使用它:

with n as (
      select row_number() over (order by (select null)) as n
      from master..spt_values
     )
select t.conf#, dateadd(day, 1, t.date), 1 as number, t.rev / t.numbers
from t join
     n
     on n <= t.numbers;

您还可以使用临时计数/数字表

例子

Select [Conf#]
      ,[Date]
      ,[Numbers] = 1
      ,[Rev] = Rev/A.Numbers
 From YourTable A
 Join ( 
        Select Top 1000 N=Row_Number() Over (Order By (Select NULL)) From master..spt_values n1, master..spt_values n2
      ) B on B.N<=A.Numbers
 Order By CONF# Desc

退货

Conf#   Date        Numbers Rev
24720   01/10/2014  1       35.00
24628   25/09/2014  1       100.00
24437   11/09/2014  1       225.00
24437   11/09/2014  1       225.00
24007   04/08/2014  1       5.00
24007   04/08/2014  1       5.00
24007   04/08/2014  1       5.00

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM