写一个查询 returns all parents on the top and then children
Write a query that returns all parents on top and then children
Table结构:
|--------------------------------|-------------|
|branchid |branchcode |parentid|branchtypeid |
|-----------------------|--------|-------------|
|438 |UKHQR |438 | 2 |
|-----------|-----------|--------|-------------|
|539 |UKBRS |438 | 1 |
|-----------|-----------|--------|-------------|
|3683 |UKSNL |438 | 2 |
|-----------|-----------|--------|-------------|
|3110 |UKNNX |3683 | 1 |
|-----------|-----------|--------|-------------|
|987 |FNOLR |987 | 2 |
|-----------|-----------|--------|-------------|
|1014 |FNHLK |987 | 1 |
|-----------|-----------|--------|-------------|
|3371 |FNHPO |987 | 2 |
|-----------|-----------|--------|-------------|
|990 |FNAAA |3371 | 1 |
|--------------------------------|-------------|
级别
branchid
和parentid
相同且branchtypeid
为2的branchcode
是第一个parent分支。
A branchcode
其 branchid
和 parentid
不 相同但 branchtypeid
是 2是第二个 parent 分支,否则是 child 分支。
Child 分支应按照其 parent 分支的排序方式进行排序。
需要输出
|--------------------------------|-------------|
|branchid |branchcode |parentid|branchtypeid |
|-----------------------|--------|-------------|
|438 |UKHQR |438 | 2 |
|-----------|-----------|--------|-------------|
|987 |FNOLR |987 | 2 |
|-----------|-----------|--------|-------------|
|3683 |UKSNL |438 | 2 |
|-----------|-----------|--------|-------------|
|3371 |FNHPO |987 | 2 |
|-----------|-----------|--------|-------------|
|539 |UKBRS |438 | 1 |
|-----------|-----------|--------|-------------|
|3110 |UKNNX |3683 | 1 |
|-----------|-----------|--------|-------------|
|1014 |FNHLK |987 | 1 |
|-----------|-----------|--------|-------------|
|990 |FNAAA |3371 | 1 |
|--------------------------------|-------------|
我已经做过的事情:
SELECT branchcode,branchid,parentid
FROM branches
START WITH parentid IN ( SELECT parentid FROM branches where parentid = branchid)
CONNECT BY NOCYCLE PRIOR parentid = branchid
ORDER SIBLINGS BY parentid;
您的代码的主要问题 - 假设您想要返回所有级别的数据 - 是您只获得具有顶级父级的行 - 即级别 1 和 2。那是因为您的 start with
子句正在寻找任何父 ID;然后您的 connect by
正在以错误的方式搜索。所以你查询得到六行:
BRANCHCODE BRANCHID PARENTID
---------- ---------- ----------
UKHQR 438 438
UKBRS 539 438
UKSNL 3683 438
FNOLR 987 987
FNHLK 1014 987
FNHPO 3371 987
.. 都带有两个原始顶级 ID 之一,438 或 987。
如果你修复这些问题,首先获取两个真正的顶级父级(而不是使用子查询)然后反转连接方式:
SELECT branchcode, branchid, parentid
FROM branches
START WITH parentid = branchid
CONNECT BY NOCYCLE parentid = PRIOR branchid
ORDER SIBLINGS BY parentid;
BRANCHCODE BRANCHID PARENTID
---------- ---------- ----------
UKHQR 438 438
UKBRS 539 438
UKSNL 3683 438
UKNNX 3110 3683
FNOLR 987 987
FNHLK 1014 987
FNHPO 3371 987
FNAAA 990 3371
...您将以更正常的顺序获得所有 8 行。顺便说一下, nocycle
只是因为定义顶级的方式而需要;根据我的经验,根元素父 ID 为空更为常见。无论如何,另一种避免循环的方法是:
CONNECT BY parentid = PRIOR branchid AND branchid != PRIOR parentid
但我离题了。您可以添加更多信息,包括层次结构的缩进视图:
SELECT branchcode, branchid, parentid,
lpad(' ', level - 1, ' ') || branchcode as nestedbranch
FROM branches
START WITH parentid = branchid
CONNECT BY NOCYCLE parentid = PRIOR branchid
ORDER SIBLINGS BY parentid;
BRANCHCODE BRANCHID PARENTID NESTEDBRANCH
---------- ---------- ---------- ---------------
UKHQR 438 438 UKHQR
UKBRS 539 438 UKBRS
UKSNL 3683 438 UKSNL
UKNNX 3110 3683 UKNNX
FNOLR 987 987 FNOLR
FNHLK 1014 987 FNHLK
FNHPO 3371 987 FNHPO
FNAAA 990 3371 FNAAA
但是您说您希望所有父项都位于顶部,这有点奇怪,并且让既是父项又是子项的行处于不确定状态。您可以通过在排序中使用 case 表达式来实现这一点,可能包括上下文的根元素(以及有用的级别),例如:
SELECT branchcode, branchid, parentid,
CONNECT_BY_ROOT(branchcode) AS rootbranch,
lpad(' ', level - 1, ' ') || branchcode as nestedbranch
FROM branches
START WITH parentid = branchid
CONNECT BY NOCYCLE parentid = PRIOR branchid
ORDER BY CASE WHEN branchid = parentid THEN 1 ELSE 2 END, -- puts all parents first
CONNECT_BY_ROOT(branchid), level, branchcode;
BRANCHCODE BRANCHID PARENTID ROOTBRANCH NESTEDBRANCH
---------- ---------- ---------- ---------- ---------------
UKHQR 438 438 UKHQR UKHQR
FNOLR 987 987 FNOLR FNOLR
UKBRS 539 438 UKHQR UKBRS
UKSNL 3683 438 UKHQR UKSNL
UKNNX 3110 3683 UKHQR UKNNX
FNHLK 1014 987 FNOLR FNHLK
FNHPO 3371 987 FNOLR FNHPO
FNAAA 990 3371 FNOLR FNAAA
但这似乎仍然不是很有用...所以也许您真的想让每个父项都在其子项之前,而较早的查询确实如此。
Table结构:
|--------------------------------|-------------|
|branchid |branchcode |parentid|branchtypeid |
|-----------------------|--------|-------------|
|438 |UKHQR |438 | 2 |
|-----------|-----------|--------|-------------|
|539 |UKBRS |438 | 1 |
|-----------|-----------|--------|-------------|
|3683 |UKSNL |438 | 2 |
|-----------|-----------|--------|-------------|
|3110 |UKNNX |3683 | 1 |
|-----------|-----------|--------|-------------|
|987 |FNOLR |987 | 2 |
|-----------|-----------|--------|-------------|
|1014 |FNHLK |987 | 1 |
|-----------|-----------|--------|-------------|
|3371 |FNHPO |987 | 2 |
|-----------|-----------|--------|-------------|
|990 |FNAAA |3371 | 1 |
|--------------------------------|-------------|
级别
branchid
和parentid
相同且branchtypeid
为2的branchcode
是第一个parent分支。A
branchcode
其branchid
和parentid
不 相同但branchtypeid
是 2是第二个 parent 分支,否则是 child 分支。Child 分支应按照其 parent 分支的排序方式进行排序。
需要输出
|--------------------------------|-------------|
|branchid |branchcode |parentid|branchtypeid |
|-----------------------|--------|-------------|
|438 |UKHQR |438 | 2 |
|-----------|-----------|--------|-------------|
|987 |FNOLR |987 | 2 |
|-----------|-----------|--------|-------------|
|3683 |UKSNL |438 | 2 |
|-----------|-----------|--------|-------------|
|3371 |FNHPO |987 | 2 |
|-----------|-----------|--------|-------------|
|539 |UKBRS |438 | 1 |
|-----------|-----------|--------|-------------|
|3110 |UKNNX |3683 | 1 |
|-----------|-----------|--------|-------------|
|1014 |FNHLK |987 | 1 |
|-----------|-----------|--------|-------------|
|990 |FNAAA |3371 | 1 |
|--------------------------------|-------------|
我已经做过的事情:
SELECT branchcode,branchid,parentid
FROM branches
START WITH parentid IN ( SELECT parentid FROM branches where parentid = branchid)
CONNECT BY NOCYCLE PRIOR parentid = branchid
ORDER SIBLINGS BY parentid;
您的代码的主要问题 - 假设您想要返回所有级别的数据 - 是您只获得具有顶级父级的行 - 即级别 1 和 2。那是因为您的 start with
子句正在寻找任何父 ID;然后您的 connect by
正在以错误的方式搜索。所以你查询得到六行:
BRANCHCODE BRANCHID PARENTID
---------- ---------- ----------
UKHQR 438 438
UKBRS 539 438
UKSNL 3683 438
FNOLR 987 987
FNHLK 1014 987
FNHPO 3371 987
.. 都带有两个原始顶级 ID 之一,438 或 987。
如果你修复这些问题,首先获取两个真正的顶级父级(而不是使用子查询)然后反转连接方式:
SELECT branchcode, branchid, parentid
FROM branches
START WITH parentid = branchid
CONNECT BY NOCYCLE parentid = PRIOR branchid
ORDER SIBLINGS BY parentid;
BRANCHCODE BRANCHID PARENTID
---------- ---------- ----------
UKHQR 438 438
UKBRS 539 438
UKSNL 3683 438
UKNNX 3110 3683
FNOLR 987 987
FNHLK 1014 987
FNHPO 3371 987
FNAAA 990 3371
...您将以更正常的顺序获得所有 8 行。顺便说一下, nocycle
只是因为定义顶级的方式而需要;根据我的经验,根元素父 ID 为空更为常见。无论如何,另一种避免循环的方法是:
CONNECT BY parentid = PRIOR branchid AND branchid != PRIOR parentid
但我离题了。您可以添加更多信息,包括层次结构的缩进视图:
SELECT branchcode, branchid, parentid,
lpad(' ', level - 1, ' ') || branchcode as nestedbranch
FROM branches
START WITH parentid = branchid
CONNECT BY NOCYCLE parentid = PRIOR branchid
ORDER SIBLINGS BY parentid;
BRANCHCODE BRANCHID PARENTID NESTEDBRANCH
---------- ---------- ---------- ---------------
UKHQR 438 438 UKHQR
UKBRS 539 438 UKBRS
UKSNL 3683 438 UKSNL
UKNNX 3110 3683 UKNNX
FNOLR 987 987 FNOLR
FNHLK 1014 987 FNHLK
FNHPO 3371 987 FNHPO
FNAAA 990 3371 FNAAA
但是您说您希望所有父项都位于顶部,这有点奇怪,并且让既是父项又是子项的行处于不确定状态。您可以通过在排序中使用 case 表达式来实现这一点,可能包括上下文的根元素(以及有用的级别),例如:
SELECT branchcode, branchid, parentid,
CONNECT_BY_ROOT(branchcode) AS rootbranch,
lpad(' ', level - 1, ' ') || branchcode as nestedbranch
FROM branches
START WITH parentid = branchid
CONNECT BY NOCYCLE parentid = PRIOR branchid
ORDER BY CASE WHEN branchid = parentid THEN 1 ELSE 2 END, -- puts all parents first
CONNECT_BY_ROOT(branchid), level, branchcode;
BRANCHCODE BRANCHID PARENTID ROOTBRANCH NESTEDBRANCH
---------- ---------- ---------- ---------- ---------------
UKHQR 438 438 UKHQR UKHQR
FNOLR 987 987 FNOLR FNOLR
UKBRS 539 438 UKHQR UKBRS
UKSNL 3683 438 UKHQR UKSNL
UKNNX 3110 3683 UKHQR UKNNX
FNHLK 1014 987 FNOLR FNHLK
FNHPO 3371 987 FNOLR FNHPO
FNAAA 990 3371 FNOLR FNAAA
但这似乎仍然不是很有用...所以也许您真的想让每个父项都在其子项之前,而较早的查询确实如此。