简体   繁体   English

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

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

I have a table that I need to split the columns on based one a date column and another column for values.我有一个表,我需要根据一个日期列和另一个值列来拆分列。

Essentially when there numbers column is greater than one, I need to split that column up on the same date until until that column equals one.本质上,当数字列大于一时,我需要在同一日期将该列拆分,直到该列等于一。

For example, this is the dataset that comes in例如,这是进来的数据集

+----------------------------------------------+
|     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          |
+----------------------------------------------+

The result I'm looking for我正在寻找的结果

+----------------------------------------------+
|     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          |
+----------------------------------------------+

The result set comes back with those rows greater than one broken up.结果集返回时将大于一的行分解。 The rev is split evenly among the rows broken up. rev 在分解的行中平均分配。

I'm trying to write a cursor for this我正在尝试为此编写 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

I'm think that the code needs to run the to divide by how many it is past one, so if the number is 5, revenue has to be divided by 5 and split evenly, this is where I'm stuck我认为代码需要运行以除以它超过一的数量,所以如果数字是 5,则收入必须除以 5 并平均分配,这就是我卡住的地方

Don't use a cursor.不要使用 cursor。 Use a recursive CTE:使用递归 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;

If you have a numbers or tally table handy, you can use that as well:如果你手边有一个数字或计数表,你也可以使用它:

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;

You can also use an ad-hoc tally/numbers table您还可以使用临时计数/数字表

Example例子

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

Returns退货

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