使用SQL实现作业的相关性

dzhpxtsq  于 2022-10-04  发布在  Oracle
关注(0)|答案(1)|浏览(275)

我有一个Oracle表,其中有3列-计划名称,作业名称和前置任务。一个职务可以有多个条目,因为它可以有多个满足条件作为前置条件。例如,

A可能有任何前置任务,也可能没有前置任务(有些计划可能有,但不是强制性的,认为这是计划的第一项工作)

  • A是B的前身
  • B是C的前身
  • D不能有任何前身
  • C&D都是E的前身

表数据看起来像这样(我刚刚嘲笑了这个表--但真正的表看起来非常杂乱,有数千个作业,作业名称是字母数字,长度为8个字符。每个时间表有数百个作业)。

| SCHEDULE | JOB | PREDECESSOR |
|----------|-----|-------------|
| SCHD_A   | A   | XYZ         |
| SCHD_A   | B   | A           |
| SCHD_A   | C   | B           |
| SCHD_A   | D   |     NULL    |
| SCHD_A   | E   | C           |
| SCHD_A   | E   | D           |

您能帮助在SQL中以相同的顺序实现这一点吗?对于此输出,排序顺序更为重要。我需要按照作业的前身依赖项的顺序检索作业列表。另外,我只需要列出任何给定工作的直接或直接前任,如下所示:

| SCHEDULE | JOB | PREDECESSOR |
|----------|-----|-------------|
| SCHD_A   | A   | XYZ         |
| SCHD_A   | B   | A           |
| SCHD_A   | C   | B           |
| SCHD_A   | D   |     NULL    |
| SCHD_A   | E   | C,D         |

我尝试使用CONNECT子句,但我的查询不正确,并且没有给出预期的结果。

我尝试使用LISTAGG,但它只列出了多个依赖项,并且没有考虑排序顺序。

感谢CLNS

6tdlim6h

6tdlim6h1#

以下是使用LISTAGG()分析函数的示例

WITH
    a_tbl AS
        (
            Select 'SCHD_A' "SCHEDULE", 'A' "JOB", 'XYZ' "PREDECESSOR" From Dual Union All
            Select 'SCHD_A' "SCHEDULE", 'B' "JOB", 'A'   "PREDECESSOR" From Dual Union All
            Select 'SCHD_A' "SCHEDULE", 'C' "JOB", 'B'   "PREDECESSOR" From Dual Union All
            Select 'SCHD_A' "SCHEDULE", 'D' "JOB", Null  "PREDECESSOR" From Dual Union All
            Select 'SCHD_A' "SCHEDULE", 'E' "JOB", 'C'   "PREDECESSOR" From Dual Union All
            Select 'SCHD_A' "SCHEDULE", 'E' "JOB", 'D'   "PREDECESSOR" From Dual 
        )

Select DISTINCT
    SCHEDULE "SCHEDULE",
    JOB "JOB",
    LISTAGG(PREDECESSOR, ', ') WITHIN GROUP (Order By PREDECESSOR) OVER(PARTITION BY SCHEDULE, JOB) "PREDECESSOR"
From
    a_tbl
Order By
    SCHEDULE,
    JOB

结果应该是:

Schedule|作业|前任
-|-|
SCHD_A|A|XYZ
SCHD_A|B|A
SCHD_A|C|B
SCHD_A|D|
SCHD_A|E|C,D

LISTAGG()不会对结果行进行排序,它会对返回的列表进行排序,这意味着如果您这样做:

LISTAGG(PREDECESSOR, ', ') WITHIN GROUP (Order By PREDECESSOR DESC) OVER(PARTITION BY SCHEDULE, JOB) "PREDECESSOR"

..。那么您的聚合前置任务列表将是**‘D,C’**而不是‘C,D’。您可以使用类似于上面的SELECT语句的ORDER BY子句对结果行进行排序-如果您将该ORDER BY子句更改为

...
From
    a_tbl
Order By 
    PREDECESSOR,
    SCHEDULE,
    JOB

结果应该是

Schedule|作业|前任
-|-|
SCHD_A|B|A
SCHD_A|C|B
SCHD_A|E|C,D
SCHD_A|A|XYZ
SCHD_A|D|

致敬..。

相关问题