Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/73.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 使用子查询将记录更新到自己的表中_Sql_Sql Server - Fatal编程技术网

Sql 使用子查询将记录更新到自己的表中

Sql 使用子查询将记录更新到自己的表中,sql,sql-server,Sql,Sql Server,我有一个日历表,我正试图用它来处理一些周末和假日的问题 结构简单: CREATE TABLE calendar ( daterank INT, thedate DATE ); 其思想是每个记录都有一个日期排名,用于比较目的。非假日工作日具有递增的daterank,周末和假日的daterank等于紧接前一个非假日工作日 为非假日工作日设置daterank比我想象的要容易,但设置周末和假日比我想象的要复杂 数据的子集: daterank thedate 881

我有一个日历表,我正试图用它来处理一些周末和假日的问题

结构简单:

CREATE TABLE calendar
(
    daterank INT,
    thedate DATE
);
其思想是每个记录都有一个日期排名,用于比较目的。非假日工作日具有递增的daterank,周末和假日的daterank等于紧接前一个非假日工作日

为非假日工作日设置daterank比我想象的要容易,但设置周末和假日比我想象的要复杂

数据的子集:

daterank    thedate

881         2013-05-21
882         2013-05-22
883         2013-05-23
884         2013-05-24
NULL        2013-05-25
NULL        2013-05-26
885         2013-05-27
886         2013-05-28
887         2013-05-29
888         2013-05-30
889         2013-05-31
NULL        2013-06-01
在上面的例子中,我想用884替换5/25和5/26的空值,5/24的值,6/1的空值,889,等等

什么不起作用:

UPDATE calendar c1
SET c1.daterank = (
    SELECT MAX(c2.daterank)
    FROM calendar c2
    WHERE c2.thedate < c1.thedate
    AND c2.daterank IS NOT NULL
)
WHERE daterank IS NULL
;

有什么想法吗?

你可以使用一个古怪的更新,我相信这应该可以:

CREATE CLUSTERED INDEX idx_Cal ON calendar (daterank)
GO

DECLARE @Prev_Dt_Rank BIGINT

UPDATE  calendar
SET     daterank =  CASE WHEN daterank IS NULL THEN @Prev_Dt_Rank
                                             ELSE daterank
                                        END                                                                                                                                                         
        ,@Prev_Dt_Rank = daterank
FROM    calendar
WITH (TABLOCKX)
OPTION (MAXDOP 1)
GO
索引是必需的,第一个daterank不能为空。
有些人不喜欢这种奇怪的更新,但在这种情况下,确保它正常工作并不重要。

您不能为要更新的表使用别名

UPDATE calendar 
SET daterank = (
    SELECT MAX(c2.daterank)
    FROM calendar c2
    WHERE c2.thedate < calendar.thedate
    AND c2.daterank IS NOT NULL
)
WHERE daterank IS NULL

您可以使用以下方法获得结果:

;with cte as
(
  select daterank, thedate
  from calendar
  where daterank is null
) 
update c
set c.daterank = d.daterank
from cte c
cross apply
(
  select top 1 daterank, thedate
  from calendar d
  where d.thedate < c.thedate
    and d.daterank is not null
  order by daterank desc
) d;

这是我的尝试

;WITH cte AS
(
  SELECT t.r, t.d
    FROM t 
   WHERE t.r IS NOT NULL
)
, tbl AS
(
  SELECT
    (
      SELECT cte.r
        FROM cte
       WHERE cte.d = (SELECT MAX(sub.d)
                        FROM cte sub
                       WHERE sub.d <= t.d)
    ) AS r,
    t.d
  FROM t 
)

UPDATE t
   SET t.r = tbl.r
  FROM t
  JOIN tbl ON tbl.d = t.d
 WHERE t.r IS NULL

SELECT * FROM t

所以你有一个日历表来处理假日问题,而你没有指出这个日期是否是假日?真奇怪。