如何用表B和表C的连接所返回的按日期排列的计数更新表A中按日期排列的计数。

问题描述 投票:0回答:1

我可以用一个临时表来做。是否可以在一个更新查询中完成这两个步骤?所有可能的日期已经存在于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
tsql join sql-update multiple-tables
1个回答
1
投票

我同意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(...)上连接),根据数据的分布情况,它可能会运行得更快。判断它是否运行得更快的唯一方法是尝试一下。

© www.soinside.com 2019 - 2024. All rights reserved.