Tsql 如何使用从表B和表C的联接返回的按日期计数更新表A中的按日期计数

Tsql 如何使用从表B和表C的联接返回的按日期计数更新表A中的按日期计数,tsql,join,sql-update,multiple-tables,Tsql,Join,Sql Update,Multiple Tables,我可以使用临时表来完成此操作是否可以在单个更新查询中执行这两个步骤? TargetTable中已存在所有可能的日期(无需插入)。 我希望使它更有效,因为它经常在成批数据定期流入表T2时运行 表T1:本批次中插入或更新的单个日期列表 表T2:datetime2(3)字段后跟多个数据字段,对于任何特定日期,可以是数千 目标:更新TargetTable:date字段,后跟int字段,以按日期保存总记录(可能刚进入T2,也可能是附加到T2中已有记录的附加记录) 我同意Zohar Peled的建议。使用通

我可以使用临时表来完成此操作是否可以在单个更新查询中执行这两个步骤? TargetTable中已存在所有可能的日期(无需插入)。 我希望使它更有效,因为它经常在成批数据定期流入表T2时运行

表T1:本批次中插入或更新的单个日期列表

表T2:datetime2(3)字段后跟多个数据字段,对于任何特定日期,可以是数千

目标:更新TargetTable:date字段,后跟int字段,以按日期保存总记录(可能刚进入T2,也可能是附加到T2中已有记录的附加记录)


我同意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;
以下是有关常用表表达式的详细信息:


完成此操作后,您可能会从中受益的另一件事是向表T2添加一个新列,数据类型为DATE。这个新列的值可以是Cast(T2.DateTime为DATE)。它甚至可能是一个(持久化的)计算列。然后在新列上添加索引。如果然后在新列上联接(而不是在表达式转换(…)上联接),则根据数据的分布情况,它可能会运行得更快。判断它是否运行得更快的唯一方法是试用。

使用cte而不是临时表。那应该更有效率。谢谢你,佐哈尔。我用CTE替换了临时工作台结构,并经历了轻微的改进。在分别运行CHECKPOINT和DROPCLEANBUFFERS之后,我最初的测试耗时27秒,而CTE则耗时26秒。我之所以选择CTE解决方案,是因为它更容易理解。提示:如果你想解决性能问题,你应该开始一个新的问题。实际执行计划是开始调查的地方。有关在问题中包含执行计划的方法,请参见。表和索引的DDL也应该包括在内。我将尝试一下。谢谢。修改T2表并重新填充它们花了相当长的时间,但是添加一个“日期”字段作为持久计算字段绝对值得。使用临时表时,执行时间从27秒降至11秒,使用CTE时,执行时间从26秒降至7秒。当我向新的“日期”字段添加索引时,执行时间下降到3秒!这接近10倍的改善。当然,没有免费的午餐-插入原始数据现在需要1.3倍的时间,但是系统现在总的来说要快得多。非常感谢。@Gil我很高兴你的表现有了很大的提高。如果我的回答对您有帮助,您可以选择它作为问题的解决方案。
;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;