当前位置: 首页 > 知识库问答 >
问题:

如何在Sybase中填充缺少的值(外部应用和派生表在MSSQL中工作,但在Sybase不工作)

云俊名
2023-03-14

我有一些带有日期和数值的表格;一些数值丢失了。我希望这些丢失的值用最后日期可用的值填充。

我需要这样做:

    < li >在Sybase数据库中,我对该数据库只有读取权限;我可以创建临时表,但不能创建永久表或永久视图 < li >在我拥有完全访问权限的Microsoft SQL Server 2019(版本15)数据库中

我发现如何做到这一点在微软SQL服务器,但不是在赛贝斯。

更新:如果我运行选择@@version我得到

Adaptive Server Enterprise/16.0 SP02 PL08 Instrumented

我需要从

+-------+-------+
| date  | value |
+-------+-------+
| 1-Nov |   100 |
| 2-Nov |       |
| 3-Nov |       |
| 4-Nov |   110 |
| 5-Nov |       |
| 6-Nov |   105 |
+-------+-------+

to(见星号):

+-------+--------+
| date  | value  |
+-------+--------+
| 1-Nov |   100  |
| 2-Nov |   *100 |
| 3-Nov |   *100 |
| 4-Nov |   110  |
| 5-Nov |   *110 |
| 6-Nov |   105  |
+-------+--------+

我在这里找到了一个例子

在SQL Server中,它运行时没有错误,但不会更新任何内容。在Sybase,根本不运行。我明白了:

关键字top附近的语法不正确

这是一个可复制的例子

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

外部应用程序工作与微软SQL但它似乎不支持赛贝斯:在赛贝斯我得到

“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

这是和以前一样的链接。这段代码在SQL塞弗雷尔工作,但是赛贝斯告诉我:

不能在UPDATE或DELETE语句的FROM子句中使用派生表

我的代码:

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

共有2个答案

孟财
2023-03-14

根据需要回填的NULLS的数量,最终将有大约50%的行需要更新。

在我遇到的所有数据库中,这种情况都需要CREATE TABLE… AS SELECT,而不是批量更新。并且-在我的示例中,我避免使用关键字,如DATEVALUE

因此 - 这是一个完整的示例 - 使用 LAST_VALUE( ...忽略空值)。

DROP TABLE IF EXISTS indata;
CREATE TABLE
indata(dt,val) AS (
          SELECT DATE '1-Nov-2021',100
UNION ALL SELECT DATE '2-Nov-2021',NULL
UNION ALL SELECT DATE '3-Nov-2021',NULL
UNION ALL SELECT DATE '4-Nov-2021',110
UNION ALL SELECT DATE '5-Nov-2021',NULL
UNION ALL SELECT DATE '6-Nov-2021',105
);

DROP TABLE IF EXISTS outdata;
CREATE TABLE outdata AS
SELECT
  dt
, LAST_VALUE(val IGNORE NULLS) OVER(ORDER BY dt) AS val
FROM indata
;

ALTER TABLE indata RENAME TO indata_old;
-- sp_rename indata, indata_old;
ALTER TABLE outdata  RENAME TO indata;
-- sp_rename indata, indata; -- do you rename tables like this in Sybase?
SELECT * FROM indata;
-- out      dt     | val 
-- out ------------+-----
-- out  2021-11-01 | 100
-- out  2021-11-02 | 100
-- out  2021-11-03 | 100
-- out  2021-11-04 | 110
-- out  2021-11-05 | 110
-- out  2021-11-06 | 105
林星阑
2023-03-14

可以使用一些“基本”子查询语法执行此操作。。。

使用选择来填补空白的一个想法(例如,OP使用选择进入):

select  mt1.*,isnull(mt1.my_value,
                        (select mt2.my_value
                         from   #my_test mt2
                         where  mt2.my_date = (select   max(my_date)
                                                from    #my_test mt3
                                                where   mt3.my_date < mt1.my_date
                                                and     mt3.my_value is not NULL))) as new_value
from    #my_test mt1
order by mt1.my_date           -- for display purposes
go

 my_date                         my_value    new_value
 ------------------------------- ----------- -----------
             Nov  1 2021 12:00AM         100         100
             Nov  2 2021 12:00AM        NULL         100
             Nov  3 2021 12:00AM        NULL         100
             Nov  4 2021 12:00AM         110         110
             Nov  5 2021 12:00AM        NULL         110
             Nov  6 2021 12:00AM         105         105

假设数据已经在#temp表中并且OP想要运行更新

update  #my_test
set     my_value = (select      mt2.my_value
                        from    #my_test mt2
                        where   mt2.my_date = (select   max(mt3.my_date)
                                                from    #my_test mt3
                                                where   mt3.my_date < mt1.my_date
                                                and     mt3.my_value is not NULL))

from    #my_test mt1
where   my_value is NULL
go

select * from #my_test
order by my_date
go

 my_date                         my_value
 ------------------------------- -----------
             Nov  1 2021 12:00AM         100
             Nov  2 2021 12:00AM         100
             Nov  3 2021 12:00AM         100
             Nov  4 2021 12:00AM         110
             Nov  5 2021 12:00AM         110
             Nov  6 2021 12:00AM         105

注:

    < li >(我)不清楚如果表中的“前”n行有< code>my_value=NULL(即没有要复制的“前一个”< code>my_value)我们应该做什么;如果这是一个问题,OP可以将子选择包装在一个< code>isnull(
 类似资料:
  • 问题内容: 我试图在sybase中更改我的表上的某些类型,但是当我更改它时,输出就是这个。 用户“ DBA”已锁定“表”中的行 如何解锁呢? 问题答案: 我会: 使用sa_locks确定connection_id(此处的文档) 向导致锁定表的连接发出drop connection * connection_id *语句。 小心使用!

  • 我正在使用maven,Eclipse。从Eclipse运行时一切都很好。但同样,如果部署在tomcat上,则返回http状态404。日志显示在类路径上未检测到Spring WebApplicationInitializer类型,但我正在使用web.xml。 如果有人能帮忙,我不知道这里有什么问题。筛选器和servlet映射没有问题。 securityFilter org.SpringFramewo

  • 问题内容: 我有一个ID和部门表。 表是 只需要这样的输出 问题答案: 这是我所知道的最好方法。如果有人知道更好的解决方案,请发帖: 我已经把你的桌子命名了

  • Spring-boot web应用程序在HTTPS协议的嵌入式tomcat中运行良好。同样的文件构建为war文件并部署到外部tomcat,但它现在不工作,出现404错误。 我如何在HTTPS协议中运行外部tomcat,我尝试在server.xml中取消注释SSL主机配置,但没有用。

  • 问题内容: 大多数数据库都有类似函数的功能,有时可能会有用。至少这些数据库没有这样的功能: Derby SQL Server Sybase ASE Sybase SQL Anywhere 对于SQL Server和Sybase SQL Anywhere,可以使用子查询对函数进行仿真,并且可以在此问题中看到。一个例子: 但这在Sybase ASE中不起作用。显然,子查询无权访问外部查询的引用。我得到