我可以用一个临时表来做。是否可以在一个更新查询中完成这两个步骤?所有可能的日期已经存在于TargetTable中(不需要插入).我希望能提高这个查询的效率,因为它经常运行,因为一批数据周期性地倒入表T2中。
表T1:在这批数据中插入或更新的单个日期的列表。
表T2:datetime2(3)字段后面有几个数据字段,对于任何特定的日期来说,可能是数千个。
目标:更新TargetTable:日期字段,后面是int字段,按日期保存总记录(可能是刚进入T2的记录,也可能是附加到T2现有记录上的额外记录)。
select T1.date as TargetDate, count(*) as CountF1
into #Temp
from T1 inner join T2
on T1.date = cast(T2.DateTime as date)
group by T1.date
update TargetTable
set TargetField1 = CountF1
from #Temp inner join TargetTable
on TargetDate = TargetTable.Date
我同意Zohar Peled的建议。使用一个 "通用表表达式",它通常被缩写为 "CTE"。CTE可以代替你方案中的临时表。你通过使用WITH关键字来编写CTE,记住,在许多情况下,你需要在WITH关键字之前有一个分号(如果你喜欢,也可以在前一个语句的末尾)。然后,解决方案看起来像这样。
;WITH CTE AS
(
SELECT T1.date AS TargetDate, Count(*) AS CountF1
FROM T1 INNER JOIN T2
ON T1.date = Cast(T2.DateTime AS DATE)
GROUP BY T1.date
)
UPDATE TargetTable
SET TargetField1 = CTE.CountF1
FROM CTE INNER JOIN TargetTable
ON CTE.TargetDate = TargetTable.Date;
这里有更多关于常见表格表达式的信息。
https:/docs.microsoft.comen-ussqlt-sqlquerieswith-common-table-expression-transact-sql。
在做完这些工作之后,那么你可能会从另一件事中受益,那就是在表T2中添加一个新的列,数据类型为DATE。这个新列的值可以是Cast(T2.DateTime AS DATE)。它甚至可能是一个(持久化的)计算列。然后在这个新列上添加一个索引。如果你然后在新列上连接(而不是在表达式Cast(...)上连接),根据数据的分布情况,它可能会运行得更快。判断它是否运行得更快的唯一方法是尝试一下。