如果聚合值错误 - SQL Server/Oracle/Firebird 从相同 table 中的聚合更新

Update from aggregate in same table if aggregate value wrong - SQL Server/Oracle/Firebird

我有一个 table 分组任务:

我需要修复(更新)组记录的 tt_fromdate 字段值,如果它们与基础任务中的 min(tt_fromdate) 不匹配(它们总是有一个值)。

尽我所能修复它们

update tt_plan_task g
set tt_fromdate=
 (select min(t.tt_fromdate) from tt_plan_task t
  where (t.tt_group_id=g.tt_plan_task_id))
where (g.tt_plantype=1)

此语句避免了我在许多(SQL 服务器)答案中看到的 UPDATE FROM 语法——Firebird 不支持该语法。

有 2 个并发症

  1. 我只想在 g.tt_fromdate <> min(t.tt_fromdate) 时进行更新,所以我必须在外部 where.
    添加对 min(tt_fromdate) 的引用 我尝试为聚合使用别名并引用它,但这让我无处可去(语法错误)

  2. SQL 服务器不喜欢更新中的 table 别名,但 solutions like these 再次使用 UPDATE FROM 语法 ;-( 我该如何解决那么呢?

如何将 1. 和 2. 绑定到我的更新语句中以使其有效?
如标题所述,这需要在 SQL Server、Oracle 和 Firebird

中执行

注意:由于组可以包含组,因此理想情况下应该执行更新 'from the bottom up',即首先执行最深的组。
但由于这只是对损坏数据库的粗略更正,所以对所有组进行一次 'lineair' 传递就足够了。

要解决 SQL 服务器更新 table 别名的非标准方式,请不要使用任何别名。

关于在 SET 子句和 WHERE 子句中都使用聚合结果,我想所有 DBMS 使用的唯一方法是编写两次聚合查询。

update tt_plan_task
set tt_fromdate =
(
  select min(t.tt_fromdate) 
  from tt_plan_task t
  where t.tt_group_id = tt_plan_task.tt_plan_task_id
)
where (tt_plantype=1)
and 
(
  tt_fromdate <>
  (
    select min(t.tt_fromdate) 
    from tt_plan_task t
    where t.tt_group_id = tt_plan_task.tt_plan_task_id
  )
);