The problem
I have some tables with dates and numerical values; some numerical values are missing. I want those missing values to be filled in with the value available at the last date.
I need to do it:
- In a Sybase database, to which I only have read access; I can create temporary tables but not any permanent tables nor permanent views
- In a Microsoft SQL Server 2019 (Version 15) database, to which I have full access
I have found how to do it in Microsoft SQL Server, but not in Sybase.
UPDATE: If I run select @@version
I get
Adaptive Server Enterprise/16.0 SP02 PL08 Instrumented
E.g. I need to go from
+-------+-------+
| date | value |
+-------+-------+
| 1-Nov | 100 |
| 2-Nov | |
| 3-Nov | |
| 4-Nov | 110 |
| 5-Nov | |
| 6-Nov | 105 |
+-------+-------+
to (see the asterisks):
+-------+--------+
| date | value |
+-------+--------+
| 1-Nov | 100 |
| 2-Nov | *100 |
| 3-Nov | *100 |
| 4-Nov | 110 |
| 5-Nov | *110 |
| 6-Nov | 105 |
+-------+--------+
Attempt #1
I found an example here
In SQL Server, it runs without errors but it doesn't update anything. In Sybase, it doesn't run at all. I get:
incorrect syntax near the keyword top
This is a reproducible example
CREATE TABLE #my_test (my_date datetime, my_value float NULL )
go
INSERT INTO #my_test SELECT '1-Nov-2021',100
INSERT INTO #my_test SELECT '2-Nov-2021',NULL
INSERT INTO #my_test SELECT '3-Nov-2021',NULL
INSERT INTO #my_test SELECT '4-Nov-2021',110
INSERT INTO #my_test SELECT '5-Nov-2021',NULL
INSERT INTO #my_test SELECT '6-Nov-2021',105
go
UPDATE #my_test
set my_value = (
select top 1 b.my_value
from #my_test b
where b.my_date < a.my_date and b.my_date = a.my_date and b.my_value is not null
order by b.my_date desc
)
from #my_test a
where a.my_value is null
go
Attempt #2
Outer apply works with Microsoft SQL but it doesn't seem supported in Sybase: in Sybase I get
Incorrect syntax near 'outer'
update #my_test
set my_value = coalesce(pr.my_value, nx.my_value)
from #my_test m
outer apply --next non-null value
(
select top 1 *
from #my_test x
where x.my_value is not null
and x.my_date > m.my_date
order by my_date
) nx
outer apply -- previous non-null
(select top 1 *
from #my_test x
where x.my_value is not null
and x.my_date < m.my_date
order by my_date desc
) pr
where m.my_value is null
Attempt #3
This was in the same link as before. This code works in SQL Sevrer but Sybase tells me:
You cannot use a derived table in the FROM clause of an UPDATE or DELETE statement
My code:
update #my_test set #my_test.my_value = tt.NewAmount
from #my_test t
inner join (
select my_date, coalesce(min(my_value) over (order by my_date desc ROWS BETWEEN 1 PRECEDING AND CURRENT ROW),
min(my_value) over (order by my_date asc ROWS BETWEEN 1 PRECEDING AND CURRENT ROW)) NewAmount
from #my_test t
) tt on tt.my_date = t.my_date
where t.my_value is null