我有以下两个表
CREATE TABLE Ep
([E] varchar(9), [M] varchar(9), [DTE] DATETIME)
;
INSERT INTO Ep
([E], [M], [DTE])
VALUES
('1595861-1', '1595861-1', CONVERT(datetime, '2002-11-26 14:18:00', 20)),
('1595904-1', '1595904-1', CONVERT(datetime, '2002-11-24 15:15:00', 20)),
('1596298-1', '1596298-1', CONVERT(datetime, '2002-12-17 11:12:00', 20)),
('1596357-1', '1596357-1', CONVERT(datetime, '2002-12-09 19:57:00', 20)),
('1596369-1', '1596369-1', CONVERT(datetime, '2002-12-11 06:00:00', 20)),
('1596370-1', '1596370-1', CONVERT(datetime, '2002-12-19 12:31:00', 20)),
('1596473-2', '1596473-1', CONVERT(datetime, '2002-12-15 08:39:00', 20)),
('1596473-3', '1596473-1', CONVERT(datetime, '2002-12-20 08:39:00', 20)),
('1596473-4', '1596473-1', CONVERT(datetime, '2002-12-13 08:39:00', 20)),
('1596473-5', '1596473-1', CONVERT(datetime, '2002-12-16 08:39:00', 20)),
('1596473-1', '1596473-1', CONVERT(datetime, '2002-12-14 08:39:00', 20))
;
CREATE TABLE Mp
([E] varchar(9), [M] varchar(9), [DTE] DATETIME)
;
INSERT INTO Mp
([E], [M], [DTE])
VALUES
('', '1595861-1', CONVERT(datetime, '2002-11-26 14:18:00', 20)),
('', '1595904-1', CONVERT(datetime, '2002-11-24 15:15:00', 20)),
('', '1596298-1', CONVERT(datetime, '2002-12-17 11:12:00', 20)),
('', '1596357-1', CONVERT(datetime, '2002-12-09 19:57:00', 20)),
('', '1596369-1', CONVERT(datetime, '2002-12-11 06:00:00', 20)),
('', '1596370-1', CONVERT(datetime, '2002-12-19 12:31:00', 20)),
('', '1596473-1', CONVERT(datetime, '2002-12-17 08:39:00', 20))
;
目前,我正在通过[E]
上的匹配更新Mp
表格中的[M]
字段,其中DTE
字段(位于Mp
)位于certian范围(比如+ -3天)。目前执行此操作的查询是
UPDATE [Mp]
SET [E] = [Ep].[E]
FROM [Mp] INNER JOIN [Ep]
ON [Mp].[M] = [Ep].[M]
WHERE [Mp].[DTE] BETWEEN [Ep].[DTE] - 3 AND [Ep].[DTE] + 3;
这会将[Mp].[E]
的{{1}}更新为[Mp].[M] = N'1596473-1'
。 Essentailly SQL Server发现的第一个有效的条目。但是,我想更新此查询,以便SQL Server在所需日期范围内的1596473-2
字段上匹配(就像现在一样),但是对于最接近[M]
值的[Ep].[DTE]
值。 {1}} [Mp].[DTE]
的值。
我已经考虑过以下方式添加2002-12-17 08:39:00
子句
DATEDIFF
显然,我无法做到这一点,但我不确定如何对此进行修改以使其有效。更新后[Mp]的最终数据应为
UPDATE [Mp]
SET [E] = [Ep].[E]
FROM [Mp] INNER JOIN [Ep]
ON [Mp].[M] = [Ep].[M]
WHERE [Mp].[DTE] BETWEEN [Ep].[DTE] - 3 AND [Ep].[DTE] + 3
ORDER BY DATEDIFF(minutes, [Mp].[DTE], [Ep].[DTE]);
感谢您的时间。
答案 0 :(得分:5)
请先检查CTE产生的数据作为输出
对于最近的数据,我根据DATEDIFF()函数提取的时差计算使用SQL ROW_NUMBER function和Partition By子句。为了消除以前和以后的记录,我使用了ABS()数学函数。
select
*,
ROW_NUMBER() over (partition by [Mp].[M] order by abs(datediff(mi, [Mp].[DTE], [Ep].[DTE]))) as rn,
abs(datediff(mi, [Mp].[DTE], [Ep].[DTE])) diff
from Mp
left join Ep
on [Mp].[M] = [Ep].[M]
WHERE [Mp].[DTE] BETWEEN dateadd(dd,-3,[Ep].[DTE]) AND dateadd(dd,3,[Ep].[DTE])
然后在UPDATE命令中使用相同的CTE表达式,如下所示,可以将所需数据填充到目标数据库表中
;with cte as (
select
[Mp].[M] as M,
[Ep].E as E,
ROW_NUMBER() over (partition by [Mp].[M] order by abs(datediff(mi, [Mp].[DTE], [Ep].[DTE]))) as rn,
abs(datediff(mi, [Mp].[DTE], [Ep].[DTE])) diff
from Mp
left join Ep
on [Mp].[M] = [Ep].[M]
WHERE [Mp].[DTE] BETWEEN dateadd(dd,-3,[Ep].[DTE]) AND dateadd(dd,3,[Ep].[DTE])
)
update [Mp]
set [E] = cte.E
from [Mp]
inner join cte on [Mp].M = cte.M and cte.rn = 1
where
cte.E is not null
执行UPDATE语句后,目标表数据如下
我希望这是你需要的