简体   繁体   中英

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.

I'm trying to write a cursor for this

    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

Don't use a cursor. Use a recursive 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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