SQL Server根据参数删除不在源中的行
我有一张表,需要根据天气预报每小时更新一次。CREATETABLE和merge工作得很好,我已经用了一段时间了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],
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;