SQL:如何根据索引列添加值

时间:2016-11-11 14:48:18

标签: sql oracle

我有一个sql表,如下所示:

|value|   |position| |relates_to_position| |type|
 100  |       2    |        NULL         |    1
  50  |       6    |        NULL         |    2
  20  |       7    |           6         |    3

由此我需要创建结果表,其中添加了| relate_to_position |的所有行字段到|具有|位置的行= | relate_to_position |。

对于上表,这将是

|value| |position| |relates_to_position| |type|
100         2             NULL              1
70          6             NULL              2

我是SQL的新手,所以我很乐意提供帮助。我使用的数据库是Oracle XE 11.只有一个级别的relate_to_position,这意味着如果设置了relev_to_position,则没有其他行会引用此行。

2 个答案:

答案 0 :(得分:3)

如果我们只假设1级的层次结构。如果多层次的层次结构变得更有趣。

SELECT A.Value+coalesce(B.Value,0) as Value
     , A.Position
     , A.Relates_to_Position
     , A.Type
FROM Table A
LEFT JOIN Table B
  on B.Relates_To_Position = A.Position
WHERE A. Relate_to_Position is null

这样做的是自联接,因此它将相关记录放在同一行上。然后它会删除所有那些带有值related_to_position的记录,因为它们将被添加到父行。

我们使用LEFT连接,因为并非所有记录都具有相关值,我们使用coalesce来确保不会尝试添加null。 (coalesce采用第一个非空值)

不确定为什么你需要返回relev_To_Position,因为它总是为空..

答案 1 :(得分:2)

如果您可以拥有多个级别的层次结构并且它们都需要总结到根位置,那么以下应该可以解决这个问题:

WITH sample_data AS (SELECT 100 VALUE, 2 position, NULL relates_to_position, 1 TYPE FROM dual UNION ALL
                     SELECT 50 VALUE, 6 position, NULL relates_to_position, 2 TYPE FROM dual UNION ALL
                     SELECT 20 VALUE, 7 position, 6 relates_to_position, 3 TYPE FROM dual UNION ALL
                     SELECT 10 VALUE, 8 position, 7 relates_to_position, 3 TYPE FROM dual)
SELECT  SUM(VALUE) VALUE,
        root_position position,
        root_type TYPE
FROM    (SELECT value,
                position,
                TYPE,
                connect_by_root(position) root_position,
                connect_by_root(TYPE) root_type
         FROM   sample_data
         CONNECT BY PRIOR position = relates_to_position
         START WITH relates_to_position IS NULL)
GROUP BY root_position,
         root_type;

     VALUE   POSITION       TYPE
---------- ---------- ----------
       100          2          1
        80          6          2