【问题标题】:SQL Oracle merge two rows into oneSQL Oracle 将两行合并为一
【发布时间】:2018-04-10 09:28:08
【问题描述】:

我到处找,但在这里找不到我的答案。 查询的表:

Temptable

id   Value  P   money1    money2     difference
1    B      O   100       null       -100
1    B      S   null      100        100
1    E      O   100       null       -100
1    E      S   null      100        100
1    O      O   100       null       -100
1    O      S   null      100        100
2    B      O   456       null       -456
2    B      S   null      456        456
2    E      O   456       null       -456
2    E      S   null      456        456
2    O      O   456       null       -456
2    O      S   null      456        456

我想要的是将行与相同的 id 结合起来。 这样查询后的结果应该是:

id   Value  P   money1    money2     difference
1    E      O   100       100        0
1    E      S   100       100        0
1    B      O   100       100        0
1    B      S   100       100        0
1    O      O   100       100        0
1    O      S   100       100        0
2    E      O   456       456        0
2    E      S   456       456        0
2    B      O   456       456        0
2    B      S   456       456        0
2    O      O   456       456        0
2    O      S   456       456        0

所以如果 id 1 money2 为 null,则该值应该用填充 money2 的 id 1 填充。这是因为我需要有差异小于 1 的记录,并且表格交付时的值是 on不同的列。

【问题讨论】:

  • 每个 id 一行不是更好吗?
  • 这也是一种选择,我真的只需要合并行。我不知道删除一行会不会更好。
  • 每个唯一 ID 是否只有 2 条记录?
  • 我编辑了表格和预期的结果,每个id会有6条记录。

标签: sql oracle merge


【解决方案1】:

我猜你只需要一个分组:

SELECT t.id,
       t.value,
       SUM(money1) AS money1,
       SUM(t.money2)  AS money2,
       SUM(difference) AS difference
  FROM temptable t
 GROUP BY t.id, t.value

编辑:我看到您更改了示例数据。您可以使用解析函数获得新结果:

SELECT t.id,
       t.value,
       t.p,
       SUM(t.money1) OVER (PARTITION BY t.id, t.value) AS money1,
       SUM(t.money2) OVER (PARTITION BY t.id, t.value) AS money2,
       SUM(difference) OVER (PARTITION BY t.id, t.value) AS difference
  FROM temptable t

这样,您将打印所有行

【讨论】:

  • 您的回答正是我想要的!感谢您的帮助。
  • 可悲的是,在真正检查过之后,我注意到如果我将 P 留在分区之外,所有的钱都会被合并。所以对于 id 1,我到处都是 300。如果我在分区中设置 P 的钱不会像我的示例结果那样被填充,但是 column1 的总和在第 1 列的任何地方都被填充,对于 column2 也是如此
  • 为什么?分区依据是 id 和 value。至于您的样本数据,您应该得到 100,因为每个 id/value 组合只有两行
  • 如果您使用 MIN() 或 MAX() 而不是 SUM(),则在计算 money1 和 money2 时,您也可以仅按 id 进行分区。这样,您将获得 id 的所有 6 行的最大非空值。我不确定你现在想做什么
【解决方案2】:

试试这个:

SELECT id, `value`, SUM(money1) money1, SUM(money2) money2, SUM(difference) difference
FROM Temptable
GROUP BY id, `value`;

【讨论】:

    【解决方案3】:

    通过sumnvl 的贡献来使用它:

    select max(id) id, value, 
           sum(nvl(money1,0)) money1, sum(nvl(money2,money1)) money2,
           sum(nvl(money2,money1)) - sum(nvl(money1,0)) difference
      from Temptable
     group by id, value;
    

    【讨论】:

    • 如果我使用它,所有的 null 值都会变为 0,但不是我想要的值。
    【解决方案4】:

    我认为你想要的是update,而不是MERGE,使用COALESCENVL

    UPDATE Temptable
    SET  money1 = COALESCE(money1, money2)
        ,money2 = COALESCE(money2, money1)
        ,difference = COALESCE(money1, money2) - COALESCE(money2, money1);
    

    Demo

    【讨论】:

      猜你喜欢
      • 2016-01-23
      • 1970-01-01
      • 2015-05-27
      • 2017-09-24
      • 1970-01-01
      • 2022-12-18
      • 1970-01-01
      • 1970-01-01
      • 2021-11-27
      相关资源
      最近更新 更多