【问题标题】:Cannot figure out logic to update a table无法弄清楚更新表的逻辑
【发布时间】:2016-07-05 02:09:11
【问题描述】:

我有下表。

表格:ABCD

每当 A 列发生变化时,B 列的值为 1。现在我必须更新如下表。我怎样才能做到这一点?

【问题讨论】:

  • (1) Oracle 和 Teradata 是不同的数据库。用您真正使用的数据库标记问题。 (2) 如果 A 值是连续的并且从 1 开始,您只需将 B 设置为 A - 1
  • 存储从表中计算出来的值通常是个坏主意。 (例如,如果 A=1 行被删除,则所有 B 值都无效。)改为创建视图,或使用触发器。)
  • 根据您的示例,它是B=A-1

标签: sql oracle teradata


【解决方案1】:

您可以使用相关子查询来做到这一点:

update t
    set b = (select sum(t2.b) from t t2 where t2.A <= t.A);

这是标准 SQL,应该可以在 Oracle 或 Teradata 中使用。

【讨论】:

  • 如果您需要在 A 组中进行部分更改,那么它不会仅将其应用于当前行和所有后续行,但也会将其应用于组中的前面行.不确定这是否是 OP 的要求,因为示例数据没有显示这种情况。
【解决方案2】:

让我们举一个稍微复杂一点的例子(B 的变化与A 的变化无关):

Oracle 设置

CREATE TABLE ABCD( A, B ) AS
SELECT 1, 0 FROM DUAL UNION ALL
SELECT 1, 0 FROM DUAL UNION ALL
SELECT 1, 1 FROM DUAL UNION ALL
SELECT 2, 1 FROM DUAL UNION ALL
SELECT 2, 0 FROM DUAL UNION ALL
SELECT 3, 0 FROM DUAL UNION ALL
SELECT 3, 1 FROM DUAL UNION ALL
SELECT 3, 0 FROM DUAL;

更新

UPDATE ABCD t1
SET    b = (
             SELECT sm
             FROM   (
               SELECT ROWID AS id,
                      SUM( b ) OVER ( ORDER BY a, ROWNUM ) AS sm
               FROM   ABCD
             ) t2
             WHERE t1.ROWID = t2.ID
           );

输出

SELECT * FROM ABCD;

A B
- -
1 0
1 0
1 1
2 2
2 2
3 2
3 3
3 3

(注意:这是一个 Oracle 解决方案;我不知道它是否适用于 Teradata。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-19
    • 1970-01-01
    • 2012-05-17
    • 1970-01-01
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 2013-03-05
    相关资源
    最近更新 更多