Oracle - sys_connect_by_path功能

时间:2017-08-22 15:43:08

标签: oracle plsql

我在表

中有以下输入数据
+-----------+-------+-----------------+-----------------+------------------+-------------------+
device_count| dmc_id| firmware_version| charging_group_id|image_prerequisite| count_within_dmcid|
+-----------+-------+-----------------+-----------------+------------------+-------------------+
| 5         | 3345  |SU.B             |0000000000000000 |SU.A              | 93                |
| 6         | 3345  |SU.C             |0000000000000000 |SU.B              | 93                |
| 8         | 3345  |SU.D             |0000000000000000 |SU.C              | 93                |
| 8         | 3345  |SU.E             |0000000000000000 |SU.C              | 93                |
| 20        | 3345  |SU.F             |0000000000000000 |SU.D              | 93                |
| 20        | 3345  |SU.F             |0000000000000000 |SU.E              | 93                |
| 10        | 3345  |SU.G             |0000000000000000 |SU.F              | 93                |
| 11        | 3345  |SU.H             |0000000000000000 |SU.F              | 93                |
| 20        | 3345  |SU.I             |0000000000000000 |SU.G              | 93                |
| 20        | 3345  |SU.I             |0000000000000000 |SU.H              | 93                |
| 5         | 3345  |SU.A             |0000000000000000 |null              | 93                |
| 40        | 408   |RT2              |0000000000000000 |RT1               | 24028             |
| 24        | 408   |RT3              |0000000000000000 |RT2               | 24028             |
| 18        | 408   |RT4              |0000000000000000 |RT3               | 24028             |
| 2109      | 408   |RT1              |0000000000000000 |null              | 24028             |
| 1         | 1422  |RT1              |0000000000000000 |null              | 7                 |
| 1         | 1422  |RT2              |0000000000000000 |RT1               | 7                 |
| 1         | 408   |RT1              |HFOTA-0000000041 |null              | 1                 |
| 1         | 408   |RT1              |HFOTA-0000000334 |null              | 2                 |
| 1         | 408   |RT1              |HFOTA-0000000359 |null              | 1                 |
| 1         | 408   |RT1              |HFOTA-0000000441 |null              | 1                 |
| 1         | 408   |RT1              |HFOTA-0000001885 |null              | 2                 |
| 4         | 408   |SVP01            |0000000000000000 |null              | 24028             |
| 11        | 408   |Sanity01         |0000000000000000 |null              | 24028             |
| 1         | 408   |Sanity1          |0000000000000000 |null              | 24028             |
| 6         | 408   |TB_HT01          |0000000000000000 |null              | 24028             |
| 1         | 408   |TEST_1           |0000000000000000 |null              | 24028             |
| 5         | 408   |TK_ST001         |0000000000000000 |null              | 24028             |
| 2         | 3345  |FW.D             |0000000000000000 |FW.C              | 24028             |
| 8         | 3345  |FW.E             |0000000000000000 |FW.D              | 24028             |
| 4         | 3345  |FW.F             |0000000000000000 |FW.E              | 24028             |
+-----------+-------+-----------------+-----------------+------------------+-------------------+

我正在使用以下查询来创建firmware_version链并查找累积计数。

WITH t1 AS
  (SELECT device_count,
    dmc_id,
    CASE
      WHEN COUNT(image_prerequisite) OVER (PARTITION BY dmc_id, charging_group_id, image_prerequisite) > 1
      THEN 
      MIN(firmware_version) 
      --WITHIN GROUP (ORDER BY firmware_version) 
      OVER (PARTITION BY dmc_id, charging_group_id, image_prerequisite) || '+N'
      ELSE firmware_version
    END firmware_version,
    charging_group_id,
    image_prerequisite,
    count_within_dmcid
  FROM dm_temp_summing_dvc_by_fw
  ),
  t2 AS
  (SELECT SUM(device_count) device_count,
    dmc_id,
    firmware_version,
    charging_group_id,
    image_prerequisite,
    count_within_dmcid
  FROM t1
  GROUP BY dmc_id,
    firmware_version,
    charging_group_id,
    image_prerequisite,
    count_within_dmcid
  ),
  t3 AS
  (SELECT t.*,
    LEVEL lev,
    sys_connect_by_path(firmware_version, '/') AS chain,
    connect_by_root(firmware_version) root_fw,
    row_number() OVER (PARTITION BY dmc_id, charging_group_id, firmware_version, connect_by_root(firmware_version) ORDER BY LEVEL DESC, sys_connect_by_path(firmware_version, '/')) rn
  FROM t2 t
    START WITH image_prerequisite                                    IS NULL
    CONNECT BY nocycle PRIOR regexp_substr(firmware_version, '[^+]*') = image_prerequisite
  AND PRIOR dmc_id                                                    = dmc_id
  AND PRIOR charging_group_id                                         = charging_group_id
  )
SELECT chain,
  root_fw,
  firmware_version AS fw,
  device_count     AS cnt,
  dmc_id,
  charging_group_id,
  count_within_dmcid,
  SUM(device_count) over(PARTITION BY dmc_id, charging_group_id, root_fw ORDER BY lev DESC) AS cumm,
  lev,
  rn
FROM t3
ORDER BY dmc_id,
  charging_group_id,
  lev DESC;

结果查询返回:它没有返回firmware_versions FW.D,FW.E,FW.F的链,因为我们使用START WITH image_prerequisite IS NULL。 请建议一种方法,我们可以解决没有起点(图像先决条件)为NULL的固件链。

CHAIN                                         ROOT_FW    FW                     CNT     DMC_ID CG_ID            LEV        COUNT_WITHIN_DMCID         RN       CUMM
--------------------------------------------- ---------- --------------- ---------- ---------- ---------------- ---------- ------------------ ---------- ----------
/RT1/RT2/RT3/RT4                              RT1        RT4                     18        408 0000000000000000  4              24028          1         18
/RT1/RT2/RT3                                  RT1        RT3                     24        408 0000000000000000  3              24028          1         42
/RT1/RT2                                      RT1        RT2                     40        408 0000000000000000  2              24028          1         82
/SVP01                                        SVP01      SVP01                    4        408 0000000000000000  1              24028          1          4
/RT1                                          RT1        RT1                   2109        408 0000000000000000  1              24028          1       2191
/Sanity01                                     Sanity01   Sanity01                11        408 0000000000000000  1              24028          1         11
/Sanity1                                      Sanity1    Sanity1                  1        408 0000000000000000  1              24028          1          1
/TB_HT01                                      TB_HT01    TB_HT01                  6        408 0000000000000000  1              24028          1          6
/TEST_1                                       TEST_1     TEST_1                   1        408 0000000000000000  1              24028          1          1
/TK_ST001                                     TK_ST001   TK_ST001                 5        408 0000000000000000  1              24028          1          5
/RT1                                          RT1        RT1                      1        408 HFOTA-0000000041  1                  1          1          1
/RT1                                          RT1        RT1                      1        408 HFOTA-0000000334  1                  2          1          1
/RT1                                          RT1        RT1                      1        408 HFOTA-0000000359  1                  1          1          1
/RT1                                          RT1        RT1                      1        408 HFOTA-0000000441  1                  1          1          1
/RT1                                          RT1        RT1                      1        408 HFOTA-0000001885  1                  2          1          1
/RT1/RT2                                      RT1        RT2                      1       1422 0000000000000000  2                  7          1          1
/RT1                                          RT1        RT1                      1       1422 0000000000000000  1                  7          1          2
/SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N/SU.I       SU.A       SU.I                    20       3345 0000000000000000  7                 93          1         20
/SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N            SU.A       SU.G+N                  21       3345 0000000000000000  6                 93          1         41
/SU.A/SU.B/SU.C/SU.D+N/SU.F                   SU.A       SU.F                    20       3345 0000000000000000  5                 93          1         61
/SU.A/SU.B/SU.C/SU.D+N                        SU.A       SU.D+N                  16       3345 0000000000000000  4                 93          1         77
/SU.A/SU.B/SU.C                               SU.A       SU.C                     6       3345 0000000000000000  3                 93          1         83
/SU.A/SU.B                                    SU.A       SU.B                     5       3345 0000000000000000  2                 93          1         88
/SU.A                                         SU.A       SU.A                     5       3345 0000000000000000  1                 93          1         93

预期产出:

CHAIN                                         ROOT_FW    FW                     CNT     DMC_ID CG_ID            LEV        COUNT_WITHIN_DMCID         RN       CUMM
--------------------------------------------- ---------- --------------- ---------- ---------- ---------------- ---------- ------------------ ---------- ----------
/RT1/RT2/RT3/RT4                              RT1        RT4                     18        408 0000000000000000  4              24028          1         18
/RT1/RT2/RT3                                  RT1        RT3                     24        408 0000000000000000  3              24028          1         42
/RT1/RT2                                      RT1        RT2                     40        408 0000000000000000  2              24028          1         82
/SVP01                                        SVP01      SVP01                    4        408 0000000000000000  1              24028          1          4
/RT1                                          RT1        RT1                   2109        408 0000000000000000  1              24028          1       2191
/Sanity01                                     Sanity01   Sanity01                11        408 0000000000000000  1              24028          1         11
/Sanity1                                      Sanity1    Sanity1                  1        408 0000000000000000  1              24028          1          1
/TB_HT01                                      TB_HT01    TB_HT01                  6        408 0000000000000000  1              24028          1          6
/TEST_1                                       TEST_1     TEST_1                   1        408 0000000000000000  1              24028          1          1
/TK_ST001                                     TK_ST001   TK_ST001                 5        408 0000000000000000  1              24028          1          5
/RT1                                          RT1        RT1                      1        408 HFOTA-0000000041  1                  1          1          1
/RT1                                          RT1        RT1                      1        408 HFOTA-0000000334  1                  2          1          1
/RT1                                          RT1        RT1                      1        408 HFOTA-0000000359  1                  1          1          1
/RT1                                          RT1        RT1                      1        408 HFOTA-0000000441  1                  1          1          1
/RT1                                          RT1        RT1                      1        408 HFOTA-0000001885  1                  2          1          1
/RT1/RT2                                      RT1        RT2                      1       1422 0000000000000000  2                  7          1          1
/RT1                                          RT1        RT1                      1       1422 0000000000000000  1                  7          1          2
/SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N/SU.I       SU.A       SU.I                    20       3345 0000000000000000  7                 93          1         20
/SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N            SU.A       SU.G+N                  21       3345 0000000000000000  6                 93          1         41
/SU.A/SU.B/SU.C/SU.D+N/SU.F                   SU.A       SU.F                    20       3345 0000000000000000  5                 93          1         61
/SU.A/SU.B/SU.C/SU.D+N                        SU.A       SU.D+N                  16       3345 0000000000000000  4                 93          1         77
/SU.A/SU.B/SU.C                               SU.A       SU.C                     6       3345 0000000000000000  3                 93          1         83
/SU.A/SU.B                                    SU.A       SU.B                     5       3345 0000000000000000  2                 93          1         88
/SU.A                                         SU.A       SU.A                     5       3345 0000000000000000  1                 93          1         93
/FW.D/FW.E/FW.F                               FW.D       FW.F                     4       3345 0000000000000000  3                 93          1          4
/FW.D/FW.E                                    FW.D       FW.E                     8       3345 0000000000000000  2                 93          1         12
/FW.D                                         FW.D       FW.D                     2       3345 0000000000000000  1                 93          1         14

1 个答案:

答案 0 :(得分:1)

正如我在评论中所写,如果你以这种方式修改if (Url.IsLocalUrl(returnUrl)) return Redirect(returnUrl); else return RedirectToAction("Index", "Home"); 子句:

START WITH

然后START WITH image_prerequisite IS NULL OR image_prerequisite NOT IN ( SELECT firmware_version FROM dm_temp_summing_dvc_by_fw ) 将作为链的开头 此查询:http://sqlfiddle.com/#!4/e4e13/3
得出以下结果:

FWD
WITH t1 AS
  (SELECT device_count,
    dmc_id,
    CASE
      WHEN COUNT(image_prerequisite) OVER (PARTITION BY dmc_id, charging_group_id, image_prerequisite) > 1
      THEN 
      MIN(firmware_version) 
      --WITHIN GROUP (ORDER BY firmware_version) 
      OVER (PARTITION BY dmc_id, charging_group_id, image_prerequisite) || '+N'
      ELSE firmware_version
    END firmware_version,
    charging_group_id,
    image_prerequisite,
    count_within_dmcid
  FROM dm_temp_summing_dvc_by_fw
  ),
  t2 AS
  (SELECT SUM(device_count) device_count,
    dmc_id,
    firmware_version,
    charging_group_id,
    image_prerequisite,
    count_within_dmcid
  FROM t1
  GROUP BY dmc_id,
    firmware_version,
    charging_group_id,
    image_prerequisite,
    count_within_dmcid
  ),
  t3 AS
  (SELECT t.*,
    LEVEL lev,
    sys_connect_by_path(firmware_version, '/') AS chain,
    connect_by_root(firmware_version) root_fw,
    row_number() OVER (PARTITION BY dmc_id, charging_group_id, firmware_version, connect_by_root(firmware_version) ORDER BY LEVEL DESC, sys_connect_by_path(firmware_version, '/')) rn
  FROM t2 t
    START WITH image_prerequisite IS NULL
          OR image_prerequisite NOT IN ( 
              SELECT firmware_version FROM dm_temp_summing_dvc_by_fw
        )
    CONNECT BY nocycle PRIOR regexp_substr(firmware_version, '[^+]*') = image_prerequisite
  AND PRIOR dmc_id                                                    = dmc_id
  AND PRIOR charging_group_id                                         = charging_group_id
  )
SELECT chain,
  root_fw,
  firmware_version AS fw,
  device_count     AS cnt,
  dmc_id,
  charging_group_id,
  count_within_dmcid,
  SUM(device_count) over(PARTITION BY dmc_id, charging_group_id, root_fw ORDER BY lev DESC) AS cumm,
  lev,
  rn
FROM t3
ORDER BY 1;

与预期输出的唯一差异是| CHAIN | ROOT_FW | FW | CNT | DMC_ID | CHARGING_GROUP_ID | COUNT_WITHIN_DMCID | CUMM | LEV | RN | |-----------------------------------------|----------|----------|------|--------|-------------------|--------------------|------|-----|----| | /FW.D | FW.D | FW.D | 2 | 3345 | 0000000000000000 | 24028 | 14 | 1 | 1 | | /FW.D/FW.E | FW.D | FW.E | 8 | 3345 | 0000000000000000 | 24028 | 12 | 2 | 1 | | /FW.D/FW.E/FW.F | FW.D | FW.F | 4 | 3345 | 0000000000000000 | 24028 | 4 | 3 | 1 | | /RT1 | RT1 | RT1 | 2109 | 408 | 0000000000000000 | 24028 | 2191 | 1 | 1 | | /RT1 | RT1 | RT1 | 1 | 1422 | 0000000000000000 | 7 | 2 | 1 | 1 | | /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000000041 | 1 | 1 | 1 | 1 | | /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000000334 | 2 | 1 | 1 | 1 | | /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000001885 | 2 | 1 | 1 | 1 | | /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000000441 | 1 | 1 | 1 | 1 | | /RT1 | RT1 | RT1 | 1 | 408 | HFOTA-0000000359 | 1 | 1 | 1 | 1 | | /RT1/RT2 | RT1 | RT2 | 1 | 1422 | 0000000000000000 | 7 | 1 | 2 | 1 | | /RT1/RT2 | RT1 | RT2 | 40 | 408 | 0000000000000000 | 24028 | 82 | 2 | 1 | | /RT1/RT2/RT3 | RT1 | RT3 | 24 | 408 | 0000000000000000 | 24028 | 42 | 3 | 1 | | /RT1/RT2/RT3/RT4 | RT1 | RT4 | 18 | 408 | 0000000000000000 | 24028 | 18 | 4 | 1 | | /SU.A | SU.A | SU.A | 5 | 3345 | 0000000000000000 | 93 | 93 | 1 | 1 | | /SU.A/SU.B | SU.A | SU.B | 5 | 3345 | 0000000000000000 | 93 | 88 | 2 | 1 | | /SU.A/SU.B/SU.C | SU.A | SU.C | 6 | 3345 | 0000000000000000 | 93 | 83 | 3 | 1 | | /SU.A/SU.B/SU.C/SU.D+N | SU.A | SU.D+N | 16 | 3345 | 0000000000000000 | 93 | 77 | 4 | 1 | | /SU.A/SU.B/SU.C/SU.D+N/SU.F | SU.A | SU.F | 20 | 3345 | 0000000000000000 | 93 | 61 | 5 | 1 | | /SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N | SU.A | SU.G+N | 21 | 3345 | 0000000000000000 | 93 | 41 | 6 | 1 | | /SU.A/SU.B/SU.C/SU.D+N/SU.F/SU.G+N/SU.I | SU.A | SU.I | 20 | 3345 | 0000000000000000 | 93 | 20 | 7 | 1 | | /SVP01 | SVP01 | SVP01 | 4 | 408 | 0000000000000000 | 24028 | 4 | 1 | 1 | | /Sanity01 | Sanity01 | Sanity01 | 11 | 408 | 0000000000000000 | 24028 | 11 | 1 | 1 | | /Sanity1 | Sanity1 | Sanity1 | 1 | 408 | 0000000000000000 | 24028 | 1 | 1 | 1 | | /TB_HT01 | TB_HT01 | TB_HT01 | 6 | 408 | 0000000000000000 | 24028 | 6 | 1 | 1 | | /TEST_1 | TEST_1 | TEST_1 | 1 | 408 | 0000000000000000 | 24028 | 1 | 1 | 1 | | /TK_ST001 | TK_ST001 | TK_ST001 | 5 | 408 | 0000000000000000 | 24028 | 5 | 1 | 1 | 列中的值,我真的不了解它们的计算方式。