0

I am having a bit of toruble with filling down some values in SQL. Here is an example of the way my data is structured.

ID  Date    Value  EndDate
A   1/1/17  500    6/1/17
A   2/1/17  489    6/1/17
A   3/1/17  480    6/1/17
A   4/1/17  475    6/1/17
A   5/1/17  460    6/1/17
A   6/1/17  0      6/1/17
A   7/1/17  0      6/1/17
B   4/1/17  784    8/1/17
B   5/1/17  801    8/1/17
B   6/1/17  0      8/1/17
B   7/1/17  0      8/1/17
B   8/1/17  0      8/1/17
B   9/1/17  0      8/1/17
B   10/1/17 0      8/1/17
C   2/1/17  980    7/1/17
C   3/1/17  564    7/1/17
C   4/1/17  647    7/1/17
C   5/1/17  500    7/1/17
C   6/1/17  0      7/1/17
C   7/1/17  0      7/1/17
C   8/1/17  0      7/1/17

For each group, I would like to fill down the value column to the point where the Date is equal to EndDate. The desired output would look like this

ID  Date    Value  EndDate
A   1/1/17  500    6/1/17
A   2/1/17  489    6/1/17
A   3/1/17  480    6/1/17
A   4/1/17  475    6/1/17
A   5/1/17  460    6/1/17
A   6/1/17  460    6/1/17
A   7/1/17  0      6/1/17
B   4/1/17  784    8/1/17
B   5/1/17  801    8/1/17
B   6/1/17  801    8/1/17
B   7/1/17  801    8/1/17
B   8/1/17  801    8/1/17
B   9/1/17  0      8/1/17
B   10/1/17 0      8/1/17
C   2/1/17  980    7/1/17
C   3/1/17  564    7/1/17
C   4/1/17  647    7/1/17
C   5/1/17  500    7/1/17
C   6/1/17  500    7/1/17
C   7/1/17  500    7/1/17
C   8/1/17  0      7/1/17

Any suggestions? Thanks!

Justin Klevs
  • 651
  • 6
  • 17
  • `Case when Date<=EndDate then value else 0 end as value` – xQbert Apr 19 '17 at 18:07
  • HI xQbert. I specifically need the last non zero value to be filled down when the result set is ordered by ID and Date. Does this take that ordering into account? – Justin Klevs Apr 19 '17 at 18:10
  • Oh 1 sec. I see now we' carry the prior value forward but only if the date is <= end date. I thought value contained the desired value . – xQbert Apr 19 '17 at 18:11

2 Answers2

2

You need to apply a LAST_VALUE-based logic like this: change zeroes to NULL when date <= EndDate and then look for the most recent existing value

Last_Value(CASE
             WHEN Date <= EndDate
             THEN NullIf(Value,0)
             ELSE Value
           END IGNORE NULLS)
Over (PARTITION BY ID
      ORDER BY Date)
dnoeth
  • 59,503
  • 4
  • 39
  • 56
0

Normally I'd use Lag() analytic, but I don't think teradata supports it so..

SELECT Id
     , Date
     , Case when Date<=EndDate then Lag(Value) over (order by ID, EndDate)
            else 0 end as value
     , EndDate
FROM Table

... so maybe... based on Teradata equivalent for lead and lag function of oracle

SELECT Id
     , Date
     , Case when Date<=EndDate then coalesce(MAX(Value) 
            over (Partition by 1 order by ID, EndDate ROWS BETWEEN 1 PRECEDING and 1 PRECEDING),0)
            else 0 end as value
     , EndDate
FROM Table

I've no test bed for teradata so you'll have to let us know if it works. or what error you encounter

Community
  • 1
  • 1
xQbert
  • 34,733
  • 2
  • 41
  • 62