Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.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 Server根据参数删除不在源中的行_Sql_Sql Server_Merge_Delete Row_Sql Delete - Fatal编程技术网

SQL Server根据参数删除不在源中的行

SQL Server根据参数删除不在源中的行,sql,sql-server,merge,delete-row,sql-delete,Sql,Sql Server,Merge,Delete Row,Sql Delete,我有一张表,需要根据天气预报每小时更新一次。CREATETABLE和merge工作得很好,我已经用了一段时间了 CREATE TABLE #WeatherHourly([Pk_Id][int], [ObservationDateTime] [datetime], [EffectiveDateTime] [datetime],

我有一张表,需要根据天气预报每小时更新一次。CREATETABLE和merge工作得很好,我已经用了一段时间了

CREATE TABLE #WeatherHourly([Pk_Id][int],
                            [ObservationDateTime] [datetime],    
                            [EffectiveDateTime] [datetime],
                            [Value] [decimal](18, 4)
                           )

MERGE INTO WeatherHourly AS TARGET 
USING #WeatherHourly AS Source ON Target.Pk_Id = Source.Pk_Id 
                               AND Target.EffectiveDateTime = Source.EffectiveDateTime 
WHEN MATCHED THEN
   UPDATE SET Target.Value = Source.Value,
              Target.ObservationDateTime = Source.ObservationDateTime 
WHEN NOT MATCHED BY TARGET THEN 
   INSERT ([Pk_Id], [ObservationDateTime], [EffectiveDateTime], [Value]) 
   VALUES (Source.Pk_Id, Source.ObservationDateTime, Source.EffectiveDateTime, Source.Value);
但我注意到,有时新的预测不包括我已经写入表格的旧数据。这意味着一些数据被粘住了,因为在merge语句中没有任何数据被写入/更新。此数据不再有效,因为它未包含在最新预测中。现在,只需在合并中添加一个“notmatchedbysource”就可以了,尽管它会删除所有历史记录行。由于其他原因,我目前保留历史记录,不能删除旧行,只能删除WeatherHourly表中仍然相关的行/(从昨天到任何未来日期的有效日期时间)。下面的代码是我迄今为止尝试过的,但它会删除我不想删除的所有历史记录行

Delete from WeatherHourly from WeatherHourly tRow 
left JOIN #WeatherHourly t2 ON tRow.EffectiveDateTime = t2.EffectiveDateTime and   tRow.Pk_Id = t2.Pk_Id
where t2.PK_Id is null
任何帮助都将不胜感激

为我的新方法编辑: 我想为我的原始合并使用更好的选择,使目标更符合我的要求

WITH    t2
AS
(
SELECT  *
FROM    WeatherHourly t
WHERE   EXISTS
(
SELECT * FROM #WeatherHourly r WHERE t.EffectiveDateTime = r.EffectiveDateTime AND  t.Pk_Id = r.Pk_Id
)
)
MERGE t2
AS Target
USING   #WeatherHourly
AS Source
ON Target.Pk_Id = Source.Pk_Id 
    AND Target.EffectiveDateTime = Source.EffectiveDateTime 
WHEN MATCHED THEN 
    UPDATE SET Target.Value = Source.Value,Target.ObservationDateTime = Source.ObservationDateTime 
WHEN NOT MATCHED BY TARGET THEN
    INSERT ([Pk_Id],[ObservationDateTime],[EffectiveDateTime],[Value]) 
    VALUES (SourcePk_Id,Source.ObservationDateTime,Source.EffectiveDateTime,Source.Value)
WHEN NOT MATCHED BY SOURCE THEN 
    DELETE;

这似乎是我想要的。任何批评都会有帮助。很抱歉,无论是谁要修复这一代码混乱。

为什么不删除已有的EffectiveDateTime,然后插入新的

DELETE FROM WeatherHourly
WHERE  EffectiveDateTime = ( SELECT TOP(1)
                                  EffectiveDateTime
                              FROM
                                  #WeatherHourly )


INSERT INTO WeatherHourly
(
    [Pk_Id]
    ,[ObservationDateTime]
    ,[EffectiveDateTime]
    ,[Value]
)
SELECT
    [Pk_Id]
    ,[ObservationDateTime]
    ,[EffectiveDateTime]
    ,[Value]
FROM
    #WeatherHourly

测试后这似乎很好。

请考虑不存在的模式。合并可能是有问题的,因为有十几个未解决的错误(不要介意语法编写和理解起来非常麻烦,并且不会为您购买您可能期望的并发控制-除非您添加积极的提示),而且左连接方法速度非常慢。为什么要在这里添加NOLOCK?请不要成为那种对每一个选择都不加选择的人。这可能是非常非常坏的消息。这是我工作的地方需要的,我不知道。从我的答案中删除。希望你不要在银行工作(或者在准确性非常重要的任何地方)。我不确定这是否有效,我也不完全记得我为什么选择合并路线。那是很久以前的事了。当我进行合并时,我跨越了几个不同的Pk_Id和每个Pk_Id的多个EffectiveDateTime,所有这些都使用相同的ObservationDateTime。希望这是有意义的。
TOP
没有
orderby
该怎么办?从
#WeatherHourly
中随机选择一行,并从
WeatherHourly
中删除相关行?
WITH    t2
AS
(
SELECT  * FROM WeatherHourly t
WHERE EXISTS
(
SELECT * FROM #WeatherHourly r WHERE t.EffectiveDateTime = r.EffectiveDateTime AND t.Pk_Id = r.Pk_Id
)
)
MERGE t2
AS Target
USING   #WeatherHourly
AS Source
ON Target.Pk_Id = Source.Pk_Id 
    AND Target.EffectiveDateTime = Source.EffectiveDateTime 
WHEN MATCHED THEN 
    UPDATE SET Target.Value = Source.Value,Target.ObservationDateTime = Source.ObservationDateTime 
WHEN NOT MATCHED BY TARGET THEN
    INSERT ([Pk_Id],[ObservationDateTime],[EffectiveDateTime],[Value]) 
    VALUES (SourcePk_Id,Source.ObservationDateTime,Source.EffectiveDateTime,Source.Value)
WHEN NOT MATCHED BY SOURCE THEN 
    DELETE;